Merge pull request #11647 from zexi/fix/megaraid-sn-empty

fix(baremetal): compatible with SN empty of MegaRaid
This commit is contained in:
yunion-ci-robot
2021-07-15 18:27:04 +08:00
committed by GitHub
2 changed files with 157 additions and 7 deletions
+39 -7
View File
@@ -615,6 +615,7 @@ func (adapter *MegaRaidAdaptor) BuildNoneRaid(devs []*baremetal.BaremetalStorage
type StorcliAdaptor struct {
Controller int
isSNEmpty bool
sn string
name string
}
@@ -622,6 +623,7 @@ type StorcliAdaptor struct {
func newStorcliAdaptor() *StorcliAdaptor {
return &StorcliAdaptor{
Controller: -1,
isSNEmpty: false,
sn: "",
name: "",
}
@@ -632,26 +634,56 @@ func (a StorcliAdaptor) key() string {
}
func (a *StorcliAdaptor) isComplete() bool {
if a.isSNEmpty {
return a.Controller >= 0 && a.name != ""
}
return a.Controller >= 0 && a.name != "" && a.sn != ""
}
func (a *StorcliAdaptor) parseLine(l string) {
parts := strings.Split(l, " = ")
func parseLineForStorcli(a *StorcliAdaptor, l string) {
controllerKey := "Controller"
productNameKey := "Product Name"
snKey := "Serial Number"
if !regexp.MustCompile(fmt.Sprintf("^(%s|%s|%s)\\s*=", controllerKey, productNameKey, snKey)).Match([]byte(l)) {
return
}
parts := strings.Split(l, "=")
if len(parts) != 2 {
return
}
key := parts[0]
val := parts[1]
trimBeginEndSpace := func(s string) string {
return strings.TrimLeft(strings.TrimRight(s, " "), " ")
}
key := trimBeginEndSpace(parts[0])
val := trimBeginEndSpace(parts[1])
if key == snKey && val == "" {
a.isSNEmpty = true
return
}
switch key {
case "Controller":
case controllerKey:
a.Controller, _ = strconv.Atoi(val)
case "Serial Number":
case snKey:
a.sn = val
case "Product Name":
case productNameKey:
a.name = val
}
}
func (a *StorcliAdaptor) parseLine(l string) {
parseLineForStorcli(a, l)
}
func (a *StorcliAdaptor) String() string {
return fmt.Sprintf("{controller: %d, isSNEmpty: %v, sn: %q, name: %s}", a.Controller, a.isSNEmpty, a.sn, a.name)
}
func (raid *MegaRaid) GetStorcliAdaptor() (map[string]*StorcliAdaptor, error) {
ret := make(map[string]*StorcliAdaptor)
cmd := GetCommand2("/call", "show", "|", "grep", "-iE", `'^(Controller|Product Name|Serial Number)\s='`)
@@ -0,0 +1,118 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package megactl
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestParseLineForStorcli(t *testing.T) {
type testCase struct {
name string
adapter *StorcliAdaptor
lines []string
assertFunc func(t *testing.T, a *StorcliAdaptor)
}
cases := []testCase{
{
name: "Should complete",
adapter: new(StorcliAdaptor),
lines: []string{
"Controller = 0",
"Product Name = SAS3108",
"Serial Number = 1234",
},
assertFunc: func(t *testing.T, a *StorcliAdaptor) {
assert.Equal(t, true, a.isComplete(), a.String())
assert.Equal(t, "SAS3108"+"1234", a.key())
},
},
{
name: "Should complete when no space beside '='",
adapter: new(StorcliAdaptor),
lines: []string{
"Controller=0",
"Product Name = SAS3108",
"Serial Number=1234",
},
assertFunc: func(t *testing.T, a *StorcliAdaptor) {
assert.Equal(t, true, a.isComplete(), a.String())
assert.Equal(t, "SAS3108"+"1234", a.key())
},
},
{
name: "Should parse empty SN",
adapter: new(StorcliAdaptor),
lines: []string{
"Controller = 0",
"Product Name = SAS3108",
"Serial Number =",
},
assertFunc: func(t *testing.T, a *StorcliAdaptor) {
assert.Equal(t, true, a.isComplete(), a.String())
assert.Equal(t, true, a.isSNEmpty, a.String())
assert.Equal(t, "SAS3108", a.key())
},
},
{
name: "Should parse empty SN end with space",
adapter: new(StorcliAdaptor),
lines: []string{
"Controller = 0",
"Product Name = SAS3108",
"Serial Number = ",
},
assertFunc: func(t *testing.T, a *StorcliAdaptor) {
assert.Equal(t, true, a.isComplete(), a.String())
assert.Equal(t, true, a.isSNEmpty, a.String())
assert.Equal(t, "SAS3108", a.key())
},
},
{
name: "Should not complete when no product name",
adapter: new(StorcliAdaptor),
lines: []string{
"Controller = 0",
"Serial Number = 1234",
},
assertFunc: func(t *testing.T, a *StorcliAdaptor) {
assert.Equal(t, false, a.isComplete(), a.String())
},
},
{
name: "Should not complete when no SN",
adapter: new(StorcliAdaptor),
lines: []string{
"Controller = 0",
"Product Name = SAS3108",
},
assertFunc: func(t *testing.T, a *StorcliAdaptor) {
assert.Equal(t, false, a.isComplete(), a.String())
},
},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
for _, l := range c.lines {
parseLineForStorcli(c.adapter, l)
}
c.assertFunc(t, c.adapter)
})
}
}