mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 10:46:58 +08:00
Merge pull request #11647 from zexi/fix/megaraid-sn-empty
fix(baremetal): compatible with SN empty of MegaRaid
This commit is contained in:
@@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user