From 0922bbf5f9feb65bb3b053dd7f0a97b18864b760 Mon Sep 17 00:00:00 2001 From: David Allen Date: Tue, 30 Jul 2024 14:05:55 -0600 Subject: [PATCH] Removed unused updating code and bmclib dependency and other minor changes --- internal/db/sqlite/sqlite.go | 2 +- internal/update.go | 139 +---------------------------------- internal/util/auth.go | 4 +- internal/util/net.go | 20 ++++- internal/util/path.go | 17 +++-- 5 files changed, 33 insertions(+), 149 deletions(-) diff --git a/internal/db/sqlite/sqlite.go b/internal/db/sqlite/sqlite.go index 7eb75a8..9a60240 100644 --- a/internal/db/sqlite/sqlite.go +++ b/internal/db/sqlite/sqlite.go @@ -80,7 +80,7 @@ func DeleteProbeResults(path string, results *[]magellan.ScannedResult) error { return nil } -func GetProbeResults(path string) ([]magellan.ScannedResult, error) { +func GetScannedResults(path string) ([]magellan.ScannedResult, error) { db, err := sqlx.Open("sqlite3", path) if err != nil { return nil, fmt.Errorf("failed toopen database: %v", err) diff --git a/internal/update.go b/internal/update.go index 35ed4c4..8c07dce 100644 --- a/internal/update.go +++ b/internal/update.go @@ -1,21 +1,11 @@ package magellan import ( - "context" "encoding/json" - "errors" "fmt" "net/http" - "os" - "strings" - "time" - "github.com/OpenCHAMI/magellan/internal/log" "github.com/OpenCHAMI/magellan/internal/util" - bmclib "github.com/bmc-toolbox/bmclib/v2" - "github.com/bmc-toolbox/bmclib/v2/constants" - bmclibErrs "github.com/bmc-toolbox/bmclib/v2/errors" - "github.com/sirupsen/logrus" ) type UpdateParams struct { @@ -26,110 +16,9 @@ type UpdateParams struct { TransferProtocol string } -// UpdateFirmware() uses 'bmc-toolbox/bmclib' to update the firmware of a BMC node. +// UpdateFirmwareRemote() uses 'gofish' to update the firmware of a BMC node. // The function expects the firmware URL, firmware version, and component flags to be // set from the CLI to perform a firmware update. -// -// NOTE: Multipart HTTP updating may not work since older verions of OpenBMC, which bmclib -// uses underneath, did not support support multipart updates. This was changed with the -// inclusion of support for MultipartHttpPushUri in OpenBMC (https://gerrit.openbmc.org/c/openbmc/bmcweb/+/32174). -// Also, related to bmclib: https://github.com/bmc-toolbox/bmclib/issues/341 -func UpdateFirmware(client *bmclib.Client, l *log.Logger, q *UpdateParams) error { - if q.Component == "" { - return fmt.Errorf("component is required") - } - - // open BMC session and update driver registry - ctx, ctxCancel := context.WithTimeout(context.Background(), time.Second*time.Duration(q.Timeout)) - client.Registry.FilterForCompatible(ctx) - err := client.Open(ctx) - if err != nil { - ctxCancel() - return fmt.Errorf("failed toconnect to bmc: %v", err) - } - - defer client.Close(ctx) - - file, err := os.Open(q.FirmwarePath) - if err != nil { - ctxCancel() - return fmt.Errorf("failed toopen firmware path: %v", err) - } - - defer file.Close() - - taskId, err := client.FirmwareInstall(ctx, q.Component, constants.FirmwareApplyOnReset, true, file) - if err != nil { - ctxCancel() - return fmt.Errorf("failed toinstall firmware: %v", err) - } - - for { - if ctx.Err() != nil { - ctxCancel() - return fmt.Errorf("context error: %v", ctx.Err()) - } - - state, err := client.FirmwareInstallStatus(ctx, q.FirmwareVersion, q.Component, taskId) - if err != nil { - // when its under update a connection refused is returned - if strings.Contains(err.Error(), "connection refused") || strings.Contains(err.Error(), "operation timed out") { - l.Log.Info("BMC refused connection, BMC most likely resetting...") - time.Sleep(2 * time.Second) - - continue - } - - if errors.Is(err, bmclibErrs.ErrSessionExpired) || strings.Contains(err.Error(), "session expired") { - err := client.Open(ctx) - if err != nil { - l.Log.Fatal(err, "bmc re-login failed") - } - - l.Log.WithFields(logrus.Fields{"state": state, "component": q.Component}).Info("BMC session expired, logging in...") - - continue - } - - l.Log.Fatal(err) - } - - switch state { - case constants.FirmwareInstallRunning, constants.FirmwareInstallInitializing: - l.Log.WithFields(logrus.Fields{"state": state, "component": q.Component}).Info("firmware install running") - - case constants.FirmwareInstallFailed: - ctxCancel() - l.Log.WithFields(logrus.Fields{"state": state, "component": q.Component}).Info("firmware install failed") - return fmt.Errorf("failed to install firmware") - - case constants.FirmwareInstallComplete: - ctxCancel() - l.Log.WithFields(logrus.Fields{"state": state, "component": q.Component}).Info("firmware install completed") - return nil - - case constants.FirmwareInstallPowerCyleHost: - l.Log.WithFields(logrus.Fields{"state": state, "component": q.Component}).Info("host powercycle required") - - if _, err := client.SetPowerState(ctx, "cycle"); err != nil { - ctxCancel() - l.Log.WithFields(logrus.Fields{"state": state, "component": q.Component}).Info("error power cycling host for install") - return fmt.Errorf("failed to install firmware") - } - - ctxCancel() - l.Log.WithFields(logrus.Fields{"state": state, "component": q.Component}).Info("host power cycled, all done!") - return nil - default: - l.Log.WithFields(logrus.Fields{"state": state, "component": q.Component}).Info("unknown state returned") - } - - time.Sleep(2 * time.Second) - } - - return nil -} - func UpdateFirmwareRemote(q *UpdateParams) error { url := baseRedfishUrl(&q.QueryParams) + "/redfish/v1/UpdateService/Actions/SimpleUpdate" headers := map[string]string{ @@ -143,7 +32,7 @@ func UpdateFirmwareRemote(q *UpdateParams) error { } data, err := json.Marshal(b) if err != nil { - return fmt.Errorf("failed tomarshal data: %v", err) + return fmt.Errorf("failed to marshal data: %v", err) } res, body, err := util.MakeRequest(nil, url, "POST", data, headers) if err != nil { @@ -172,27 +61,3 @@ func GetUpdateStatus(q *UpdateParams) error { } return nil } - -// func UpdateFirmwareLocal(q *UpdateParams) error { -// fwUrl := baseUrl(&q.QueryParams) + "" -// url := baseUrl(&q.QueryParams) + "UpdateService/Actions/" -// headers := map[string]string { - -// } - -// // get etag from FW inventory -// response, err := util.MakeRequest() - -// // load file from disk -// file, err := os.ReadFile(q.FirmwarePath) -// if err != nil { -// return fmt.Errorf("failed toread file: %v", err) -// } - -// switch q.TransferProtocol { -// case "HTTP": -// default: -// return fmt.Errorf("transfer protocol not supported") -// } -// return nil -// } diff --git a/internal/util/auth.go b/internal/util/auth.go index 98ef88c..9df0a11 100644 --- a/internal/util/auth.go +++ b/internal/util/auth.go @@ -29,9 +29,9 @@ func LoadAccessToken(path string) (string, error) { } // TODO: try to load token from config - testToken = viper.GetString("access_token") + testToken = viper.GetString("access-token") if testToken != "" { return testToken, nil } - return "", fmt.Errorf("failed toload token from environment variable, file, or config") + return "", fmt.Errorf("failed to load token from environment variable, file, or config") } diff --git a/internal/util/net.go b/internal/util/net.go index cdc18db..f0528f1 100644 --- a/internal/util/net.go +++ b/internal/util/net.go @@ -9,6 +9,22 @@ import ( "net/http" ) +// HTTP aliases for readibility +type HTTPHeader map[string]string +type HTTPBody []byte + +func (h HTTPHeader) Authorization(accessToken string) HTTPHeader { + if accessToken != "" { + h["Authorization"] = fmt.Sprintf("Bearer %s", accessToken) + } + return h +} + +func (h HTTPHeader) ContentType(contentType string) HTTPHeader { + h["Content-Type"] = contentType + return h +} + // GetNextIP() returns the next IP address, but does not account // for net masks. func GetNextIP(ip *net.IP, inc uint) *net.IP { @@ -35,7 +51,7 @@ func GetNextIP(ip *net.IP, inc uint) *net.IP { // // Returns a HTTP response object, response body as byte array, and any // error that may have occurred with making the request. -func MakeRequest(client *http.Client, url string, httpMethod string, body []byte, headers map[string]string) (*http.Response, []byte, error) { +func MakeRequest(client *http.Client, url string, httpMethod string, body HTTPBody, header HTTPHeader) (*http.Response, HTTPBody, error) { // use defaults if no client provided if client == nil { client = http.DefaultClient @@ -48,7 +64,7 @@ func MakeRequest(client *http.Client, url string, httpMethod string, body []byte return nil, nil, fmt.Errorf("failed to create new HTTP request: %v", err) } req.Header.Add("User-Agent", "magellan") - for k, v := range headers { + for k, v := range header { req.Header.Add(k, v) } res, err := client.Do(req) diff --git a/internal/util/path.go b/internal/util/path.go index 06611b6..19f6afe 100644 --- a/internal/util/path.go +++ b/internal/util/path.go @@ -40,31 +40,34 @@ func SplitPathForViper(path string) (string, string, string) { } // MakeOutputDirectory() creates a new directory at the path argument if -// the path does not exist +// the path does not exist. +// +// Returns the final path that was created if no errors occurred. Otherwise, +// it returns an empty string with an error. // // TODO: Refactor this function for hive partitioning or possibly move into // the logging package. // TODO: Add an option to force overwriting the path. -func MakeOutputDirectory(path string) (string, error) { +func MakeOutputDirectory(path string, overwrite bool) (string, error) { // get the current data + time using Go's stupid formatting t := time.Now() - dirname := t.Format("2006-01-01 15:04:05") + dirname := t.Format("2006-01-01") final := path + "/" + dirname // check if path is valid and directory pathExists, err := PathExists(final) if err != nil { - return final, fmt.Errorf("failed to check for existing path: %v", err) + return "", fmt.Errorf("failed to check for existing path: %v", err) } - if pathExists { + if pathExists && !overwrite { // make sure it is directory with 0o644 permissions - return final, fmt.Errorf("found existing path: %v", final) + return "", fmt.Errorf("found existing path: %v", final) } // create directory with data + time err = os.MkdirAll(final, 0766) if err != nil { - return final, fmt.Errorf("failed to make directory: %v", err) + return "", fmt.Errorf("failed to make directory: %v", err) } return final, nil }