From 4b2e8e7f38e6560fbe5997a2463b73fff18f5b01 Mon Sep 17 00:00:00 2001 From: PDeanCalnex Date: Tue, 3 Dec 2024 08:46:12 -0800 Subject: [PATCH] add functionality for different calnex firmware file formats (#427) Summary: Currently the code only works for a specific string of the filename. This can be different depending on the release that is sent. If we are doing an engineering release or full release. We normally now send files of the format calnex_combined_fw now that we have installer files for both sentinel and sentry included in the file Pull Request resolved: https://github.com/facebook/time/pull/427 Test Plan: [dev@pd-vm01.sen.local] [~/meta-time] (main *$%<>) $ ./cmd/calnex/calnex firmware --device sen050.sen.local --file sentinel_fw_v2.21.2.0.tar --insecureTLS WARN[0000] sen050.sen.local: is running 21.0.0.9718-d-20241125, latest is 21.2.0. Needs an update INFO[0000] sen050.sen.local: dry run. Not upgrading firmware [dev@pd-vm01.sen.local] [~/meta-time] (main *$%<>) $ ./cmd/calnex/calnex firmware --device sen050.sen.local --file calnex_combined_fw_R21.2.0.tar --insecureTLS WARN[0000] sen050.sen.local: is running 21.0.0.9718-d-20241125, latest is 21.2.0. Needs an update INFO[0000] sen050.sen.local: dry run. Not upgrading firmware successfully extracting the correct part of the firmware from each differently formatted file name Reviewed By: t3lurid3 Differential Revision: D66651957 Pulled By: deathowl fbshipit-source-id: b2425f6805d0312939fd62686a67589ec976b9ae --- calnex/firmware/firmware.go | 4 +- calnex/firmware/ossfirmware.go | 26 ++++++++- calnex/firmware/ossfirmware_test.go | 83 +++++++++++++++++++++++++++-- 3 files changed, 108 insertions(+), 5 deletions(-) diff --git a/calnex/firmware/firmware.go b/calnex/firmware/firmware.go index 0a4d9349..ebe44ed6 100644 --- a/calnex/firmware/firmware.go +++ b/calnex/firmware/firmware.go @@ -51,7 +51,9 @@ func (up CalnexUpgrader) ShouldUpgrade(target string, api *calnexAPI.API, fw FW, if err != nil { return false, err } - calnexVersion, err := version.NewVersion(strings.ToLower(cv.Firmware)) + //remove major version 2.17.0 -> 17.0 as this is hadware revision related + //calnexVersion, err := version.NewVersion(strings.ToLower(cv.Firmware)) + calnexVersion, err := version.NewVersion(strings.ToLower(strings.SplitN(cv.Firmware, ".", 2)[1])) if err != nil { return false, err } diff --git a/calnex/firmware/ossfirmware.go b/calnex/firmware/ossfirmware.go index 803d46ab..b8c611ff 100644 --- a/calnex/firmware/ossfirmware.go +++ b/calnex/firmware/ossfirmware.go @@ -17,7 +17,9 @@ limitations under the License. package firmware import ( + "fmt" "path/filepath" + "regexp" "strings" version "github.com/hashicorp/go-version" @@ -31,12 +33,34 @@ type OSSFW struct { // NewOSSFW returns initialized version of OSSFW func NewOSSFW(source string) (*OSSFW, error) { + var vs string + fw := &OSSFW{ filepath: source, } + basename := filepath.Base(fw.filepath) - vs := strings.ReplaceAll(strings.TrimSuffix(basename, filepath.Ext(basename)), "sentinel_fw_v", "") + // Extract version from filename + // sentinel_fw_v2.13.1.0.5583D-20210924.tar -> 13.1.0.5583 + // calnex_combined_fw_R21.0.0.9705-20241111.tar -> 21.0.0.9705 + + re := regexp.MustCompile(`(sentry_fw_|sentinel_fw_|calnex_combined_fw_)(v[0-9]\.|R)(.*)\.tar`) + + matches := re.FindStringSubmatch(basename) + + if len(matches) == 4 { + vs = matches[3] + } else { + return nil, fmt.Errorf("invalid filename, expected prefix sentinel_fw_, sentry_fw_, or calnex_combined_fw_ followed by 'v2.' or 'R': %s", basename) + } v, err := version.NewVersion(strings.ToLower(vs)) + if err != nil { + return nil, err + } + //expect major, minor, patch, build + if len(v.Segments()) != 4 { + return nil, fmt.Errorf("invalid version format, expected 4 segments: %v", v.Segments()) + } fw.version = v return fw, err } diff --git a/calnex/firmware/ossfirmware_test.go b/calnex/firmware/ossfirmware_test.go index f03c6668..66bac20b 100644 --- a/calnex/firmware/ossfirmware_test.go +++ b/calnex/firmware/ossfirmware_test.go @@ -23,9 +23,7 @@ import ( "github.com/stretchr/testify/require" ) -func TestOSSFW(t *testing.T) { - expectedFilePath := "/tmp/sentinel_fw_v2.13.1.0.5583D-20210924.tar" - expectedVersion, _ := version.NewVersion("2.13.1.0.5583d-20210924") +func checkOSSFW(t *testing.T, expectedFilePath string, expectedVersion *version.Version) { fw, err := NewOSSFW(expectedFilePath) require.NoError(t, err) @@ -37,3 +35,82 @@ func TestOSSFW(t *testing.T) { require.NoError(t, err) require.Equal(t, expectedVersion, v) } + +func checkErrorOSSFW(t *testing.T, expectedFilePath string) { + fw, err := NewOSSFW(expectedFilePath) + require.Nil(t, fw) + require.Error(t, err) +} + +func TestOSSFW(t *testing.T) { + //all files are expected to produce the same version output + //development/beta build versions (D after build number) + expectedVersiondev, _ := version.NewVersion("13.1.0.5583d-20210924") + + // Test case for sentinel_fw + expectedFilePathSentineldev := "/tmp/sentinel_fw_v2.13.1.0.5583D-20210924.tar" + checkOSSFW(t, expectedFilePathSentineldev, expectedVersiondev) + + // Test case for sentry + expectedFilePathSentrydev := "/tmp/sentry_fw_v2.13.1.0.5583D-20210924.tar" + checkOSSFW(t, expectedFilePathSentrydev, expectedVersiondev) + + // Test case for calnex_combined + expectedFilePathCalnexdev := "/tmp/calnex_combined_fw_R13.1.0.5583D-20210924.tar" + checkOSSFW(t, expectedFilePathCalnexdev, expectedVersiondev) + + //full release versions (no D) + expectedVersion, _ := version.NewVersion("13.1.0.5583-20210924") + + // Test case for sentinel_fw + expectedFilePathSentinel := "/tmp/sentinel_fw_v2.13.1.0.5583-20210924.tar" + checkOSSFW(t, expectedFilePathSentinel, expectedVersion) + + // Test case for sentry + expectedFilePathSentry := "/tmp/sentry_fw_v2.13.1.0.5583-20210924.tar" + checkOSSFW(t, expectedFilePathSentry, expectedVersion) + + // Test case for calnex_combined + expectedFilePathCalnex := "/tmp/calnex_combined_fw_R13.1.0.5583-20210924.tar" + checkOSSFW(t, expectedFilePathCalnex, expectedVersion) + + // Check errors + expectedFilePathMissingStart := "/tmp/R13.1.0.5583-20210924.tar" + checkErrorOSSFW(t, expectedFilePathMissingStart) + + //missing v2./R + expectedFilePathMissingSecond := "/tmp/sentinel_fw_13.1.0.5583-20210924.tar" + checkErrorOSSFW(t, expectedFilePathMissingSecond) + + //misspelt sintinel + expectedFilePathBadStart := "/tmp/sentrinel_fw_R13.1.0.5583-20210924.tar" + checkErrorOSSFW(t, expectedFilePathBadStart) + + //both v2. and R + expectedFilePathBadSecond := "/tmp/sentinel_fw_Rv2.13.1.0.5583-20210924.tar" + checkErrorOSSFW(t, expectedFilePathBadSecond) + + //.zip not .tar + expectedFilePathBadExtension := "/tmp/sentinel_fw_R13.1.0.5583-20210924.zip" + checkErrorOSSFW(t, expectedFilePathBadExtension) + + //HW version not 0-9 + expectedFilePathBadHWVersion := "/tmp/sentinel_fw_v10.13.1.0.5583-20210924.tar" + checkErrorOSSFW(t, expectedFilePathBadHWVersion) + + //malformed versions + expectedFilePathBadBuild1 := "/tmp/sentinel_fw_v2.13.1.0.D5583-20210924.tar" + checkErrorOSSFW(t, expectedFilePathBadBuild1) + + expectedFilePathBadBuild2 := "/tmp/sentinel_fw_v2.13.1D.0.5583-20210924.tar" + checkErrorOSSFW(t, expectedFilePathBadBuild2) + + expectedFilePathBadBuild3 := "/tmp/sentinel_fw_v2.13D.1.0.5583-20210924.tar" + checkErrorOSSFW(t, expectedFilePathBadBuild3) + + expectedFilePathBadBuild4 := "/tmp/sentinel_fw_v2.13.1..10.5583-20210924.tar" + checkErrorOSSFW(t, expectedFilePathBadBuild4) + + expectedFilePathBadBuild5 := "/tmp/sentinel_fw_v2.13.1.1.10.5583-20210924.tar" + checkErrorOSSFW(t, expectedFilePathBadBuild5) +}