mirror of
https://github.com/davidallendj/magellan.git
synced 2025-12-20 11:37:01 -07:00
Modified update command and implementation
This commit is contained in:
parent
62dd01e1ca
commit
5b390a65c2
2 changed files with 100 additions and 19 deletions
|
|
@ -8,9 +8,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
host string
|
||||||
|
port int
|
||||||
firmwarePath string
|
firmwarePath string
|
||||||
firmwareVersion string
|
firmwareVersion string
|
||||||
component string
|
component string
|
||||||
|
transferProtocol string
|
||||||
|
status bool
|
||||||
)
|
)
|
||||||
|
|
||||||
var updateCmd = &cobra.Command{
|
var updateCmd = &cobra.Command{
|
||||||
|
|
@ -22,17 +26,39 @@ var updateCmd = &cobra.Command{
|
||||||
FirmwarePath: firmwarePath,
|
FirmwarePath: firmwarePath,
|
||||||
FirmwareVersion: firmwareVersion,
|
FirmwareVersion: firmwareVersion,
|
||||||
Component: component,
|
Component: component,
|
||||||
|
TransferProtocol: transferProtocol,
|
||||||
QueryParams: magellan.QueryParams{
|
QueryParams: magellan.QueryParams{
|
||||||
|
Drivers: []string{"redfish"},
|
||||||
|
Preferred: "redfish",
|
||||||
|
Host: host,
|
||||||
User: user,
|
User: user,
|
||||||
Pass: pass,
|
Pass: pass,
|
||||||
Timeout: timeout,
|
Timeout: timeout,
|
||||||
|
Port: port,
|
||||||
|
WithSecureTLS: withSecureTLS,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
client, err := magellan.NewClient(l, &q.QueryParams)
|
|
||||||
if err != nil {
|
// check if required params are set
|
||||||
l.Log.Errorf("could not make client: %v", err)
|
if host == "" || user == "" || pass == "" {
|
||||||
|
l.Log.Fatal("requires host, user, and pass to be set")
|
||||||
}
|
}
|
||||||
err = magellan.UpdateFirmware(client, l, q)
|
|
||||||
|
// get status if flag is set and exit
|
||||||
|
if status {
|
||||||
|
err := magellan.GetUpdateStatus(q)
|
||||||
|
if err != nil {
|
||||||
|
l.Log.Errorf("could not get update status: %v", err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// client, err := magellan.NewClient(l, &q.QueryParams)
|
||||||
|
// if err != nil {
|
||||||
|
// l.Log.Errorf("could not make client: %v", err)
|
||||||
|
// }
|
||||||
|
// err = magellan.UpdateFirmware(client, l, q)
|
||||||
|
err := magellan.UpdateFirmwareRemote(q)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Log.Errorf("could not update firmware: %v", err)
|
l.Log.Errorf("could not update firmware: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -40,10 +66,15 @@ var updateCmd = &cobra.Command{
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
updateCmd.PersistentFlags().StringVar(&user, "user", "", "set the BMC user")
|
updateCmd.Flags().StringVar(&host, "host", "", "set the BMC host")
|
||||||
updateCmd.PersistentFlags().StringVar(&pass, "pass", "", "set the BMC password")
|
updateCmd.Flags().IntVar(&port, "port", 443, "set the BMC port")
|
||||||
updateCmd.PersistentFlags().StringVar(&firmwarePath, "firmware-path", "", "set the path to the firmware")
|
updateCmd.Flags().StringVar(&user, "user", "", "set the BMC user")
|
||||||
updateCmd.PersistentFlags().StringVar(&firmwareVersion, "firmware-version", "", "set the version of firmware to be installed")
|
updateCmd.Flags().StringVar(&pass, "pass", "", "set the BMC password")
|
||||||
updateCmd.PersistentFlags().StringVar(&component, "component", "", "set the component to upgrade")
|
updateCmd.Flags().StringVar(&transferProtocol, "protocol", "HTTP", "set the transfer protocol")
|
||||||
|
updateCmd.Flags().StringVar(&firmwarePath, "firmware-path", "", "set the path to the firmware")
|
||||||
|
updateCmd.Flags().StringVar(&firmwareVersion, "firmware-version", "", "set the version of firmware to be installed")
|
||||||
|
updateCmd.Flags().StringVar(&component, "component", "", "set the component to upgrade")
|
||||||
|
updateCmd.Flags().BoolVar(&withSecureTLS, "secure-tls", false, "enable secure TLS")
|
||||||
|
updateCmd.Flags().BoolVar(&status, "status", false, "get the status of the update")
|
||||||
rootCmd.AddCommand(updateCmd)
|
rootCmd.AddCommand(updateCmd)
|
||||||
}
|
}
|
||||||
|
|
@ -24,9 +24,16 @@ type UpdateParams struct {
|
||||||
FirmwarePath string
|
FirmwarePath string
|
||||||
FirmwareVersion string
|
FirmwareVersion string
|
||||||
Component string
|
Component string
|
||||||
|
TransferProtocol string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: Does not work since OpenBMC, whic bmclib uses underneath, does not
|
||||||
|
// support multipart updates. See issue: https://github.com/bmc-toolbox/bmclib/issues/341
|
||||||
func UpdateFirmware(client *bmclib.Client, l *log.Logger, q *UpdateParams) error {
|
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
|
// open BMC session and update driver registry
|
||||||
ctx, ctxCancel := context.WithTimeout(context.Background(), time.Second*time.Duration(q.Timeout))
|
ctx, ctxCancel := context.WithTimeout(context.Background(), time.Second*time.Duration(q.Timeout))
|
||||||
client.Registry.FilterForCompatible(ctx)
|
client.Registry.FilterForCompatible(ctx)
|
||||||
|
|
@ -118,22 +125,36 @@ func UpdateFirmware(client *bmclib.Client, l *log.Logger, q *UpdateParams) error
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateFirmwareV2(serverIP string, imageURI string, component string, q *QueryParams) error {
|
func UpdateFirmwareRemote(q *UpdateParams) error {
|
||||||
url := baseUrl(q) + "UpdateService/Actions/SimpleUpdate"
|
url := baseRedfishUrl(&q.QueryParams) + "/UpdateService/Actions/SimpleUpdate"
|
||||||
|
headers := map[string]string {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"cache-control": "no-cache",
|
||||||
|
}
|
||||||
b := map[string]any{
|
b := map[string]any{
|
||||||
"UpdateComponent": component, // BMC, BIOS
|
"UpdateComponent": q.Component, // BMC, BIOS
|
||||||
"TransferProtocol": "HTTP",
|
"TransferProtocol": q.TransferProtocol,
|
||||||
"ImageURI": "http://" + serverIP + "/" + imageURI,
|
"ImageURI": q.FirmwarePath,
|
||||||
}
|
}
|
||||||
data, err := json.Marshal(b)
|
data, err := json.Marshal(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not marshal data: %v", err)
|
return fmt.Errorf("could not marshal data: %v", err)
|
||||||
}
|
}
|
||||||
headers := map[string]string{
|
res, body, err := util.MakeRequest(url, "POST", data, headers)
|
||||||
"Content-Type": "application/json",
|
if err != nil {
|
||||||
"cache-control": "no-cache",
|
return fmt.Errorf("something went wrong: %v", err)
|
||||||
|
} else if res == nil {
|
||||||
|
return fmt.Errorf("no response returned (url: %s)", url)
|
||||||
}
|
}
|
||||||
res, _, err := util.MakeRequest(url, "POST", data, headers)
|
if len(body) > 0 {
|
||||||
|
fmt.Printf("%d: %v\n", res.StatusCode, string(body))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetUpdateStatus(q *UpdateParams) error {
|
||||||
|
url := baseRedfishUrl(&q.QueryParams) + "/UpdateService"
|
||||||
|
res, body, err := util.MakeRequest(url, "GET", nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("something went wrong: %v", err)
|
return fmt.Errorf("something went wrong: %v", err)
|
||||||
} else if res == nil {
|
} else if res == nil {
|
||||||
|
|
@ -141,5 +162,34 @@ func UpdateFirmwareV2(serverIP string, imageURI string, component string, q *Que
|
||||||
} else if res.StatusCode != http.StatusOK {
|
} else if res.StatusCode != http.StatusOK {
|
||||||
return fmt.Errorf("returned status code %d", res.StatusCode)
|
return fmt.Errorf("returned status code %d", res.StatusCode)
|
||||||
}
|
}
|
||||||
|
if len(body) > 0 {
|
||||||
|
fmt.Printf("%d: %v\n", res.StatusCode, string(body))
|
||||||
|
}
|
||||||
return nil
|
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("could not read file: %v", err)
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// switch q.TransferProtocol {
|
||||||
|
// case "HTTP":
|
||||||
|
// default:
|
||||||
|
// return fmt.Errorf("transfer protocol not supported")
|
||||||
|
// }
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
Loading…
Add table
Add a link
Reference in a new issue