From 5beff7912a498f775fd0b7b8c8f13223a546bde4 Mon Sep 17 00:00:00 2001 From: Markus Vahlenkamp Date: Mon, 21 Oct 2024 22:50:51 +0200 Subject: [PATCH] fix host release name nil pointer (#2250) * fix host release name nil pointer * lint * added host node to e2e test --------- Co-authored-by: Roman Dodin --- nodes/host/host.go | 29 ++------------- ...03-linux-nodes-to-bridge-and-host.clab.yml | 2 ++ utils/file.go | 35 +++++++++++++++++++ 3 files changed, 40 insertions(+), 26 deletions(-) diff --git a/nodes/host/host.go b/nodes/host/host.go index 1be522d1a..c99dc8e7b 100644 --- a/nodes/host/host.go +++ b/nodes/host/host.go @@ -7,9 +7,6 @@ package host import ( "bytes" "context" - "os" - "path/filepath" - "regexp" osexec "os/exec" @@ -19,6 +16,7 @@ import ( "github.com/srl-labs/containerlab/nodes/state" "github.com/srl-labs/containerlab/runtime" "github.com/srl-labs/containerlab/types" + "github.com/srl-labs/containerlab/utils" ) var kindnames = []string{"host"} @@ -59,30 +57,9 @@ func (*host) WithMgmtNet(*types.MgmtNet) {} // UpdateConfigWithRuntimeInfo is a noop for hosts. func (*host) UpdateConfigWithRuntimeInfo(_ context.Context) error { return nil } -// getOSRelease returns the OS release of the host by inspecting /etc/*-release. -func getOSRelease() string { - image := "N/A" - - matches, err := filepath.Glob("/etc/*-release") - if err != nil { - return image - } - dat, err := os.ReadFile(matches[0]) - if err != nil { - return image - } - // DISTRIB_DESCRIPTION exists in lsb-release, but not os-release. - // the lsb-release is coming first in the glob, so it works. - re := regexp.MustCompile(`DISTRIB_DESCRIPTION="(.*)"`) - - regexres := re.FindSubmatch(dat) - - return string(regexres[1]) -} - // GetContainers returns a basic skeleton of a container to enable graphing of hosts kinds. -func (*host) GetContainers(_ context.Context) ([]runtime.GenericContainer, error) { - image := getOSRelease() +func (h *host) GetContainers(_ context.Context) ([]runtime.GenericContainer, error) { + image := utils.GetOSRelease() return []runtime.GenericContainer{ { diff --git a/tests/01-smoke/03-linux-nodes-to-bridge-and-host.clab.yml b/tests/01-smoke/03-linux-nodes-to-bridge-and-host.clab.yml index acebdd593..20ca8936c 100644 --- a/tests/01-smoke/03-linux-nodes-to-bridge-and-host.clab.yml +++ b/tests/01-smoke/03-linux-nodes-to-bridge-and-host.clab.yml @@ -14,6 +14,8 @@ topology: cmd: ash -c "sleep 9999" br-01-03-clab: kind: bridge + hostnode: # is not used, it is here for coverage + kind: host links: - endpoints: ["l1:eth1", "br-01-03-clab:l1-eth1"] diff --git a/utils/file.go b/utils/file.go index 8fe3908cf..3860bd750 100644 --- a/utils/file.go +++ b/utils/file.go @@ -19,6 +19,7 @@ import ( "os/exec" "os/user" "path/filepath" + "regexp" "strconv" "strings" @@ -471,3 +472,37 @@ func recursiveChown(path string, uid, gid int) error { return err }) } + +var osRelease string + +// GetOSRelease returns the OS release of the host by inspecting /etc/*-release files. +func GetOSRelease() string { + // return cached result + if osRelease != "" { + return osRelease + } + osRelease = "N/A" + + matches, err := filepath.Glob("/etc/*-release") + if err != nil { + return osRelease + } + + re := regexp.MustCompile(`(DISTRIB_DESCRIPTION|PRETTY_NAME)="(.*)"`) + + for _, match := range matches { + data, err := os.ReadFile(match) + if err != nil { + log.Error(err) + } + + match := re.FindSubmatch(data) + // [0] = whole line match, [1] = left side of "=", [2] = right side of "=" + if len(match) >= 3 { + osRelease = string(match[2]) + break + } + } + + return osRelease +}