@@ -18,7 +18,13 @@ package host
1818
1919import (
2020 "context"
21+ "fmt"
22+ "regexp"
23+ "strconv"
24+ "strings"
25+ "sync"
2126
27+ "github.com/Mellanox/doca-driver-build/entrypoint/internal/constants"
2228 "github.com/Mellanox/doca-driver-build/entrypoint/internal/utils/cmd"
2329 "github.com/Mellanox/doca-driver-build/entrypoint/internal/wrappers"
2430)
@@ -31,6 +37,17 @@ func New(c cmd.Interface, osWrapper wrappers.OSWrapper) Interface {
3137 }
3238}
3339
40+ // RedhatVersionInfo contains version information for RedHat-based distributions
41+ type RedhatVersionInfo struct {
42+ // MajorVersion is the major version number (e.g., 8, 9)
43+ MajorVersion int
44+ // FullVersion is the complete version string (e.g., "8.4", "9.2")
45+ FullVersion string
46+ // OpenShiftVersion is the OpenShift version if running on RHCOS (e.g., "4.9")
47+ // If empty, this is not RHCOS
48+ OpenShiftVersion string
49+ }
50+
3451// Interface is the interface exposed by the host package.
3552type Interface interface {
3653 // GetOSType returns the name of the operating system as a string.
@@ -42,17 +59,60 @@ type Interface interface {
4259 LsMod (ctx context.Context ) (map [string ]LoadedModule , error )
4360 // RmMod unload the kernel module.
4461 RmMod (ctx context.Context , module string ) error
62+ // GetRedHatVersionInfo parses RedHat version information from /host/etc/os-release
63+ // and returns version details. Should only be called for RedHat-based distributions.
64+ GetRedHatVersionInfo (ctx context.Context ) (* RedhatVersionInfo , error )
4565}
4666
4767type host struct {
4868 cmd cmd.Interface
4969 os wrappers.OSWrapper
70+
71+ // Cache for OS type
72+ osTypeCache struct {
73+ value string
74+ err error
75+ once sync.Once
76+ }
77+
78+ // Cache for RedHat version info
79+ redhatVersionCache struct {
80+ value * RedhatVersionInfo
81+ err error
82+ once sync.Once
83+ }
5084}
5185
5286// GetOSType is the default implementation of the host.Interface.
5387func (h * host ) GetOSType (ctx context.Context ) (string , error ) {
54- // TODO: add implementation
55- return "" , nil
88+ h .osTypeCache .once .Do (func () {
89+ // Read /etc/os-release file to determine OS type
90+ osReleaseContent , err := h .os .ReadFile ("/etc/os-release" )
91+ if err != nil {
92+ h .osTypeCache .err = err
93+ return
94+ }
95+
96+ osReleaseStr := string (osReleaseContent )
97+ osReleaseStr = strings .ToLower (osReleaseStr )
98+
99+ // Check for Ubuntu (case insensitive)
100+ if strings .Contains (osReleaseStr , "ubuntu" ) {
101+ h .osTypeCache .value = constants .OSTypeUbuntu
102+ return
103+ }
104+
105+ // Check for SLES (case insensitive)
106+ if strings .Contains (osReleaseStr , "sles" ) {
107+ h .osTypeCache .value = constants .OSTypeSLES
108+ return
109+ }
110+
111+ // Default to redhat for other distributions (RHEL, CentOS, Fedora, etc.)
112+ h .osTypeCache .value = constants .OSTypeRedHat
113+ })
114+
115+ return h .osTypeCache .value , h .osTypeCache .err
56116}
57117
58118// GetDebugInfo is the default implementation of the host.Interface.
@@ -83,3 +143,95 @@ func (h *host) RmMod(ctx context.Context, module string) error {
83143 // TODO: add implementation
84144 return nil
85145}
146+
147+ // GetRedHatVersionInfo is the default implementation of the host.Interface.
148+ func (h * host ) GetRedHatVersionInfo (ctx context.Context ) (* RedhatVersionInfo , error ) {
149+ h .redhatVersionCache .once .Do (func () {
150+ // First check if this is a RedHat-based system
151+ osType , err := h .GetOSType (ctx )
152+ if err != nil {
153+ h .redhatVersionCache .err = fmt .Errorf ("failed to get OS type: %w" , err )
154+ return
155+ }
156+
157+ if osType != constants .OSTypeRedHat {
158+ h .redhatVersionCache .err = fmt .Errorf ("GetRedHatVersionInfo should only be called for RedHat-based distributions, got: %s" , osType )
159+ return
160+ }
161+
162+ // Read /host/etc/os-release file
163+ osReleaseContent , err := h .os .ReadFile ("/host/etc/os-release" )
164+ if err != nil {
165+ h .redhatVersionCache .err = fmt .Errorf ("failed to read /host/etc/os-release: %w" , err )
166+ return
167+ }
168+
169+ osReleaseStr := string (osReleaseContent )
170+
171+ // Parse the os-release content
172+ versionInfo := & RedhatVersionInfo {}
173+
174+ // Extract ID, VERSION_ID, RHEL_VERSION, and OPENSHIFT_VERSION
175+ var id , versionID , rhelVersion , openshiftVersion string
176+
177+ idMatch := regexp .MustCompile (`(?m)^ID=(.+)$` ).FindStringSubmatch (osReleaseStr )
178+ if len (idMatch ) > 1 {
179+ id = strings .Trim (idMatch [1 ], `"` )
180+ }
181+
182+ versionIDMatch := regexp .MustCompile (`(?m)^VERSION_ID=(.+)$` ).FindStringSubmatch (osReleaseStr )
183+ if len (versionIDMatch ) > 1 {
184+ versionID = strings .Trim (versionIDMatch [1 ], `"` )
185+ }
186+
187+ rhelVersionMatch := regexp .MustCompile (`(?m)^RHEL_VERSION=(.+)$` ).FindStringSubmatch (osReleaseStr )
188+ if len (rhelVersionMatch ) > 1 {
189+ rhelVersion = strings .Trim (rhelVersionMatch [1 ], `"` )
190+ }
191+
192+ openshiftVersionMatch := regexp .MustCompile (`(?m)^OPENSHIFT_VERSION=(.+)$` ).FindStringSubmatch (osReleaseStr )
193+ if len (openshiftVersionMatch ) > 1 {
194+ openshiftVersion = strings .Trim (openshiftVersionMatch [1 ], `"` )
195+ }
196+
197+ if id == "rhcos" {
198+ // This is RHCOS - use OpenShift version logic
199+ if openshiftVersion != "" {
200+ versionInfo .OpenShiftVersion = openshiftVersion
201+ } else {
202+ versionInfo .OpenShiftVersion = versionID
203+ }
204+ if versionInfo .OpenShiftVersion == "" {
205+ versionInfo .OpenShiftVersion = constants .DefaultOpenShiftVersion
206+ }
207+ versionInfo .FullVersion = versionInfo .OpenShiftVersion
208+ } else {
209+ // For RHEL and other RedHat-based distros (CentOS, Fedora, etc.)
210+ versionInfo .FullVersion = rhelVersion
211+ if versionInfo .FullVersion == "" {
212+ versionInfo .FullVersion = versionID
213+ }
214+ if versionInfo .FullVersion == "" {
215+ versionInfo .FullVersion = constants .DefaultRHELVersion
216+ }
217+
218+ // If OPENSHIFT_VERSION is present, this might be RHCOS with ID=rhel
219+ if openshiftVersion != "" {
220+ versionInfo .OpenShiftVersion = openshiftVersion
221+ }
222+ }
223+
224+ // Extract major version from full version
225+ majorVersionStr := strings .Split (versionInfo .FullVersion , "." )[0 ]
226+ majorVersion , err := strconv .Atoi (majorVersionStr )
227+ if err != nil {
228+ h .redhatVersionCache .err = fmt .Errorf ("failed to parse major version from '%s': %w" , versionInfo .FullVersion , err )
229+ return
230+ }
231+ versionInfo .MajorVersion = majorVersion
232+
233+ h .redhatVersionCache .value = versionInfo
234+ })
235+
236+ return h .redhatVersionCache .value , h .redhatVersionCache .err
237+ }
0 commit comments