Skip to content

Commit

Permalink
MTL-2348 New ncn_kernel_upgrade role
Browse files Browse the repository at this point in the history
New role and an update to the `ncn_initrd.yml` playbook
for installing new packages pertaining to NIC failures:
- New SuSE PTF Kernel mitigating Kernel Panics for any vendor during NIC
  recovery
- New Marvell driver with bugfixes for successfully recovering bonded
  QLogic NICs
Update tests to align with PR
  • Loading branch information
rustydb committed Jan 26, 2024
1 parent d15fe73 commit 8d7721c
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 42 deletions.
36 changes: 25 additions & 11 deletions pkg/cmd/cli/bios/bios.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ package bios
import (
"fmt"
"github.com/Cray-HPE/gru/pkg/auth"
"github.com/Cray-HPE/gru/pkg/cmd/cli/bios/collections"
"github.com/spf13/cobra"
"github.com/stmcginnis/gofish/redfish"
"gopkg.in/yaml.v3"
Expand All @@ -38,37 +39,50 @@ import (
"strings"
)

// Attributes is a structure for holding current BIOS attributes, pending attributes, and errors.
type Attributes struct {
// Settings is a structure for holding current BIOS attributes, pending attributes, and errors.
type Settings struct {
Attributes map[string]interface{} `json:"attributes,omitempty"`
Pending map[string]interface{} `json:"pending,omitempty"`
Error error `json:"error,omitempty"`
}

// Attributes are an array of attribute names (and optionally values).
var Attributes []string

// FromFile is a path to a file to read attributes from.
var FromFile string

// NewCommand creates the `bios` subcommand.
func NewCommand() *cobra.Command {
c := &cobra.Command{
Use: "bios",
Short: "BIOS interaction",
Long: `Interact with a host's bios`,
Hidden: false,
Use: "bios",
Short: "BIOS interaction",
Long: `Interact with a host's bios`,
TraverseChildren: true,
Args: cobra.MinimumNArgs(1),
Hidden: false,
Run: func(c *cobra.Command, args []string) {
},
}

c.PersistentFlags().StringSliceP(
c.PersistentFlags().StringArrayVarP(
&Attributes,
"attributes",
"a",
[]string{},
"Comma delimited list of attributes and values: [key[,keyN]]",
)

c.PersistentFlags().StringP(
c.PersistentFlags().StringVarP(
&FromFile,
"from-file",
"f",
"",
"Path to an INI or YAML file with bios attributes (value(s) for key(s) will be ignored)",
)

c.PersistentFlags().BoolP(
c.PersistentFlags().BoolVarP(
&collections.Virtualization,
"virtualization",
"V",
false,
Expand All @@ -85,8 +99,8 @@ func NewCommand() *cobra.Command {
// makeAttributes makes a “map[string]interface“ out of a comma separate slice of
// key=values, which are split on on '='. the resultant value is a string,
// which does not work for all attributes.
func makeAttributes(args []string) Attributes {
attributes := Attributes{}
func makeAttributes(args []string) Settings {
attributes := Settings{}
attributes.Attributes = make(map[string]interface{})

var a interface{}
Expand Down
3 changes: 3 additions & 0 deletions pkg/cmd/cli/bios/collections/virtualization.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ import (
"strings"
)

// Virtualization denotes whether to use this collection.
var Virtualization bool

var (
// IntelEnableVirtualization defines Intel Corporation BIOS settings for enabling virtualization with Intel processors.
IntelEnableVirtualization = redfish.SettingsAttributes{
Expand Down
16 changes: 8 additions & 8 deletions pkg/cmd/cli/bios/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func getBiosAttributes(host string) interface{} {
v := viper.GetViper()
var biosDecoder Decoder
var requestedAttributes []string
attributes := Attributes{}
attributes := Settings{}

if v.GetBool("pending") {
pendingAttributes := getPendingBiosAttributes(host)
Expand Down Expand Up @@ -163,7 +163,7 @@ func getBiosAttributes(host string) interface{} {
return attributes
}

func updateAttributeMap(attributes Attributes, attribute string, value any, decodedAttribute string) Attributes {
func updateAttributeMap(attributes Settings, attribute string, value any, decodedAttribute string) Settings {
if decodedAttribute != "" {
attributes.Attributes[decodedAttribute] = value
} else {
Expand All @@ -173,8 +173,8 @@ func updateAttributeMap(attributes Attributes, attribute string, value any, deco
}

// getPendingBiosAttributes gets the staged bios attributes from Bios/Settings
func getPendingBiosAttributes(host string) Attributes {
attributes := Attributes{}
func getPendingBiosAttributes(host string) Settings {
attributes := Settings{}

_, bios, err := getSystemBios(host)
if err != nil {
Expand All @@ -196,7 +196,7 @@ func getPendingBiosAttributes(host string) Attributes {
}

/*
make a simple map for checking the existence of the "Attributes" key
make a simple map for checking the existence of the "Settings" key
if it does not exist, ``bios.UpdateBiosAttributes`` still returns 200
even though no changes can actually take place
*/
Expand All @@ -207,14 +207,14 @@ func getPendingBiosAttributes(host string) Attributes {
return attributes
}

_, exists := staged["Attributes"]
if staged["Attributes"] == nil || !exists {
_, exists := staged["Settings"]
if staged["Settings"] == nil || !exists {
attributes.Error = fmt.Errorf("\"Attributes\" does not exist or is null, the BIOS/firmware may need to updated for proper Attributes support")
return attributes
}

modified := make(map[string]interface{})
for k, v := range staged["Attributes"].(map[string]interface{}) {
for k, v := range staged["Settings"].(map[string]interface{}) {
if v != bios.Attributes[k] {
modified[k] = v
}
Expand Down
35 changes: 32 additions & 3 deletions pkg/cmd/cli/bios/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,19 @@ OTHER DEALINGS IN THE SOFTWARE.
package bios

import (
"fmt"
"github.com/Cray-HPE/gru/internal/set"
"github.com/Cray-HPE/gru/pkg/cmd/cli"
"github.com/Cray-HPE/gru/pkg/cmd/cli/bios/collections"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/stmcginnis/gofish/redfish"
"os"
)

// ClearCmos determins whether or not to clear the CMOS values.
var ClearCmos bool

// NewBiosSetCommand creates the `set` subcommand for `bios`.
func NewBiosSetCommand() *cobra.Command {
c := &cobra.Command{
Expand All @@ -41,6 +46,29 @@ func NewBiosSetCommand() *cobra.Command {
Long: `Sets BIOS attributes if the attribute is found and the value is valid.`,
Args: cobra.MinimumNArgs(1),
Run: func(c *cobra.Command, args []string) {
if len(Attributes) == 0 && FromFile == "" && !collections.Virtualization && !ClearCmos {
_, err := fmt.Fprintln(
os.Stderr,
fmt.Errorf("an error occurred: at least one of the flags in the group [attributes from-file virtualization clear-cmos] is required"),
)
err = c.Help()
if err != nil {
return
}
os.Exit(1)
}
if (len(Attributes) == 0) == (FromFile == "") == collections.Virtualization == ClearCmos {
_, err := fmt.Fprintln(
os.Stderr,
fmt.Errorf("an error occurred: only one of the flags in the group [attributes from-file virtualization clear-cmos] can be specified at a time"),
)
err = c.Help()
if err != nil {
return
}
os.Exit(1)
}

v := viper.GetViper()
hosts := cli.ParseHosts(args)
a := viper.GetStringSlice("attributes")
Expand All @@ -58,7 +86,8 @@ func NewBiosSetCommand() *cobra.Command {
Hidden: false,
}

c.PersistentFlags().Bool(
c.PersistentFlags().BoolVar(
&ClearCmos,
"clear-cmos",
false,
"Clear CMOS; set all BIOS attributes to their defaults.",
Expand All @@ -68,7 +97,7 @@ func NewBiosSetCommand() *cobra.Command {
}

func setBios(host string, requestedAttributes map[string]interface{}) interface{} {
attributes := Attributes{}
attributes := Settings{}
v := viper.GetViper()

systems, bios, err := getSystemBios(host)
Expand Down Expand Up @@ -128,7 +157,7 @@ func setBios(host string, requestedAttributes map[string]interface{}) interface{
}

func resetBios(host string) interface{} {
attributes := Attributes{}
attributes := Settings{}

_, bios, err := getSystemBios(host)
if err != nil {
Expand Down
5 changes: 3 additions & 2 deletions pkg/cmd/gru/gru.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ import (
// NewCommand creates the main command for `gru`.
func NewCommand(name string) *cobra.Command {
c := &cobra.Command{
Use: name,
Short: fmt.Sprintf("Go Redfish Utility (%s)", name),
Use: name,
TraverseChildren: true,
Short: fmt.Sprintf("Go Redfish Utility (%s)", name),
Long: fmt.Sprintf(
`
%[1]s is a tool for interacting with Redfish devices. %[1]s provides a
Expand Down
12 changes: 6 additions & 6 deletions spec/functional/bios_get_attributes_spec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ It "--config ${GRU_CONF} --attributes BootTimeout 127.0.0.1:5000"
When call ./gru bios get --config "${GRU_CONF}" --attributes BootTimeout 127.0.0.1:5000
The status should equal 0
The stdout should include 'BootTimeout'
The lines of stdout should equal 3
The lines of stdout should equal 4
End

# getting a single key should return only those key in json
Expand Down Expand Up @@ -63,9 +63,9 @@ End
It "--config ${GRU_CONF} --attributes junk 127.0.0.1:5000"
When call ./gru bios get --config "${GRU_CONF}" --attributes junk 127.0.0.1:5000
The status should equal 0
The line 3 of stdout should include 'junk'
The line 3 of stdout should include '<nil>'
The lines of stdout should equal 3
The line 4 of stdout should include 'junk'
The line 4 of stdout should include '<nil>'
The lines of stdout should equal 4
End

# TODO: restore when args work with piping
Expand All @@ -85,7 +85,7 @@ It "--config ${GRU_CONF} --virtualization 127.0.0.1:5001"
The stdout should include 'Local APIC Mode'
The stdout should include 'IOMMU'
The stdout should include 'SVM Mode'
The lines of stdout should equal 7
The lines of stdout should equal 8
End

# --virtualization shortcut should return only virtualization attributes in json format (Gigabyte)
Expand All @@ -109,7 +109,7 @@ It "--config ${GRU_CONF} 127.0.0.1:5001"
The stdout should include 'Disable Block Sid'
The stdout should include 'Rome0179'
The stdout should include 'Determinism Slider'
The lines of stdout should equal 552
The lines of stdout should equal 553
End

# Gigabyte should not return friendly names on json output
Expand Down
23 changes: 12 additions & 11 deletions spec/functional/bios_get_spec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ It "--config ${GRU_CONF} 127.0.0.1:5000"
The stdout should include 'ProcessorHyperThreadingDisable'
The stdout should include 'SRIOVEnable'
The stdout should include 'VTdSupport'
The lines of stdout should equal 866
The lines of stdout should equal 867
End

# TODO: restore when args work with piping
Expand All @@ -51,26 +51,27 @@ It "--config ${GRU_CONF} --pending 127.0.0.1:5000"
When call ./gru bios get --config "${GRU_CONF}" --pending 127.0.0.1:5000
The status should equal 0
The stdout should include 'Error'
The stdout should include '"Attributes" does not exist or is null. You may need to update the BIOS/firmware'
The stdout should include '"Attributes" does not exist or is null, the BIOS/firmware may need to updated for proper Attributes support'
The lines of stdout should equal 3
End

# TODO: restore when marshaling JSON errors is fixed.
# getting pending changes should return an error if the Bios/Settings.Attributes does not exist and be valid json
It "--config ${GRU_CONF} --pending 127.0.0.1:5000 --json"
When call ./gru bios get --config "${GRU_CONF}" --pending 127.0.0.1:5000 --json
The status should equal 0
The stdout should include 'Error'
The stdout should include '\"Attributes\" does not exist or is null. You may need to update the BIOS/firmware'
The stdout should be_json
End
#It "--config ${GRU_CONF} --pending 127.0.0.1:5000 --json"
# When call ./gru bios get --config "${GRU_CONF}" --pending 127.0.0.1:5000 --json
# The status should equal 0
# The stdout should include 'error'
# The stdout should include '\"Attributes\" does not exist or is null, the BIOS/firmware may need to updated for proper Attributes support'
# The stdout should be_json
#End

# getting keys from a file should return those keys
It "--config ${GRU_CONF} --from-file ${GRU_BIOS_KV} 127.0.0.1:5000"
When call ./gru bios get --config "${GRU_CONF}" --from-file "${GRU_BIOS_KV}" 127.0.0.1:5000
The status should equal 0
The stdout should include 'BootTimeout'
The stdout should include 'SRIOVEnable'
The lines of stdout should equal 4
The lines of stdout should equal 5
End

# getting keys from a file should return those keys and be valid json
Expand All @@ -89,7 +90,7 @@ It "--config ${GRU_CONF} --virtualization 127.0.0.1:5003"
The stdout should include 'ProcAmdIOMMU'
The stdout should include 'Sriov'
The stdout should include 'ProcAmdVirtualization'
The lines of stdout should equal 6
The lines of stdout should equal 7
End

# passing a shortcut should return a limited set of pre-defined keys and be valid json
Expand Down
9 changes: 8 additions & 1 deletion spec/functional/bios_set_spec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,14 @@ BeforeAll use_valid_bios_attributes_file
It "--config ${GRU_CONF} 127.0.0.1:5000"
When call ./gru bios set --config "${GRU_CONF}" 127.0.0.1:5000
The status should equal 1
The stderr should include 'An error occurred: at least one of the flags in the group [attributes from-file virt defaults] is required'
The stderr should include 'an error occurred: at least one of the flags in the group [attributes from-file virtualization clear-cmos] is required'
End

# setting with more than one flag should fail
It "--config ${GRU_CONF} 127.0.0.1:5000"
When call ./gru bios set --config "${GRU_CONF}" --attributes foo --from-file ./baz.txt 127.0.0.1:5000
The status should equal 1
The stderr should include 'an error occurred: only one of the flags in the group [attributes from-file virtualization clear-cmos] can be specified at a time'
End

# TODO: restore when args work with piping
Expand Down

0 comments on commit 8d7721c

Please sign in to comment.