Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 50 additions & 4 deletions src/pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ var (
"XTERM_VERSION",
}

// func var to allow mocking in testing
osreleaseRead = osrelease.Read

releaseDefault string

runtimeDirectories map[string]string
Expand Down Expand Up @@ -201,7 +204,7 @@ func init() {
distroDefault = distroFallback
releaseDefault = releaseFallback

hostID, err := getHostID()
hostID, err := matchHostToSupportedDistro()
if err == nil {
if distroObj, supportedDistro := supportedDistros[hostID]; supportedDistro {
release, err := getDefaultReleaseForDistro(hostID)
Expand Down Expand Up @@ -455,20 +458,63 @@ func GetGroupForSudo() (string, error) {
// Examples:
// - host is Fedora, returned string is 'fedora'
func getHostID() (string, error) {
osRelease, err := osrelease.Read()
osRelease, err := osreleaseRead()
if err != nil {
return "", err
}

return osRelease["ID"], nil
}

// getHostIDLike returns the ID_LIKE from the os-release files
//
// Examples:
// - host is CentOS, returned []string is ['rhel', 'fedora']
func getHostIDLike() ([]string, error) {
osRelease, err := osreleaseRead()
if err != nil {
return nil, err
}

return strings.Fields(osRelease["ID_LIKE"]), nil
}

// matchHostToSupportedDistro returns the first matching distro ID of host that is supported
// if none are supported, ErrDistroUnsupported
//
// Examples:
// - host is CentOS, returned string is 'rhel'
// - host is "linux", returned error is ErrDistroUnsupported
func matchHostToSupportedDistro() (string, error) {
distroID, err := getHostID()
if err != nil {
return "", err
}

if _, ok := supportedDistros[distroID]; ok {
return distroID, nil
}

distroIDLikeVals, err := getHostIDLike()
if err != nil {
return "", err
}

for _, distroIDLike := range distroIDLikeVals {
if _, ok := supportedDistros[distroIDLike]; ok {
return distroIDLike, nil
}
}

return "", &DistroError{distroID, ErrDistroUnsupported}
}

// getHostVersionID returns the VERSION_ID from the os-release files
//
// Examples:
// - host is Fedora 32, returned string is '32'
func getHostVersionID() (string, error) {
osRelease, err := osrelease.Read()
osRelease, err := osreleaseRead()
if err != nil {
return "", err
}
Expand Down Expand Up @@ -644,7 +690,7 @@ func IsP11KitClientPresent() (bool, error) {
var p11KitClientPaths []string
var supportedDistro bool

hostID, err := getHostID()
hostID, err := matchHostToSupportedDistro()
if err == nil {
distroObj, ok := supportedDistros[hostID]
supportedDistro = ok
Expand Down
63 changes: 63 additions & 0 deletions src/pkg/utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -417,3 +417,66 @@ func TestPathExistsSymlinkTargetExists(t *testing.T) {
exists := PathExists(link)
assert.True(t, exists)
}

func TestMatchHostToSupportedDistro(t *testing.T) {
osreleaseReadStash := osreleaseRead
t.Cleanup(func() { osreleaseRead = osreleaseReadStash })

testCases := []struct {
inputOsRelease map[string]string
output string
errMsg string
}{
{
// 1) Supported ID
inputOsRelease: map[string]string{
"ID": "ubuntu",
"ID_LIKE": "debian",
},
output: "ubuntu",
},
{
// 2) Unsupported ID, first ID_LIKE is supported
inputOsRelease: map[string]string{
"ID": "centos",
"ID_LIKE": "rhel fedora",
},
output: "rhel",
},
{
// 3) Unsupported ID and first ID_LIKE, subsequent ID_LIKE is supported
inputOsRelease: map[string]string{
"ID": "rocky",
"ID_LIKE": "centos rhel fedora",
},
output: "rhel",
},
{
// 4) Neither ID nor ID_LIKE values are supported
inputOsRelease: map[string]string{
"ID": "android",
"ID_LIKE": "linux",
},
errMsg: "android: distribution is unsupported",
},
}

for _, tc := range testCases {
name := "ID=" + tc.inputOsRelease["ID"] + ", ID_LIKE=" + tc.inputOsRelease["ID_LIKE"]
t.Run(name, func(t *testing.T) {
osreleaseRead = func() (map[string]string, error) { return tc.inputOsRelease, nil }
distro, err := matchHostToSupportedDistro()

if tc.errMsg == "" {
assert.NoError(t, err)
assert.Equal(t, tc.output, distro)
} else {
assert.Error(t, err)
assert.EqualError(t, err, tc.errMsg)

var errDistroUnsupported *DistroError
assert.ErrorAs(t, err, &errDistroUnsupported)
}
})
}
}