feat(baremetal): megaraid perccli supported

This commit is contained in:
Zexi Li
2022-01-11 17:27:52 +08:00
parent 5474f9b390
commit e35fdb266b
7 changed files with 601 additions and 149 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
FROM registry.cn-beijing.aliyuncs.com/yunionio/baremetal-base:v0.3.3-2-grub
FROM registry.cn-beijing.aliyuncs.com/yunionio/baremetal-base:v0.3.3-2-grub-test
MAINTAINER "Zexi Li <lizexi@yunionyun.com>"
+1 -1
View File
@@ -1,7 +1,7 @@
#FROM --platform=linux/amd64 registry.cn-beijing.aliyuncs.com/yunionio/centos-build:1.1-4 as build
#RUN yum install -y https://iso.yunion.cn/vm-images/baremetal-pxerom-1.1.0-21092209.x86_64.rpm
#RUN yum install -y http://192.168.23.50:8083/baremetal-pxerom-1.1.0-21092209.x86_64.rpm
FROM registry.cn-beijing.aliyuncs.com/yunionio/yunionos:v0.1.1 as yunionos
FROM registry.cn-beijing.aliyuncs.com/yunionio/yunionos:v0.1.1-test as yunionos
FROM centos:8 as grub-stage
+1 -1
View File
@@ -27,7 +27,7 @@ WEBCONSOLE_BASE_VERSION = v0.2-1
webconsole-base:
$(DOCKER_BUILDX)/webconsole-base:$(WEBCONSOLE_BASE_VERSION) -f ./Dockerfile.webconsole-base .
BAREMETAL_BASE_VERSION = v0.3.3-2-grub
BAREMETAL_BASE_VERSION = v0.3.3-2-grub-test
baremetal-base:
$(DOCKER_BUILDX)/baremetal-base:$(BAREMETAL_BASE_VERSION) -f ./Dockerfile.baremetal-base .
+184
View File
@@ -0,0 +1,184 @@
// 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 (
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/baremetal/utils/raid"
"yunion.io/x/onecloud/pkg/compute/baremetal"
)
func init() {
raid.RegisterDriver(baremetal.DISK_DRIVER_MEGARAID, newRaid)
}
type iDriver interface {
GetName() string
GetAdapterConstructCmd() string
NewAdaptor(term raid.IExecTerm) iAdaptor
ClearForeignState(term raid.IExecTerm) error
}
type iAdaptor interface {
ParseLine(line string)
IsComplete() bool
Key() string
GetPhyDevs() ([]*MegaRaidPhyDev, error)
ClearJBODDisks(devs []*MegaRaidPhyDev)
GetIndex() int
GetLogicVolumes() ([]*raid.RaidLogicalVolume, error)
RemoveLogicVolumes() error
BuildRaid0(devs []*baremetal.BaremetalStorage, conf *compute.BaremetalDiskConfig) error
BuildRaid1(devs []*baremetal.BaremetalStorage, conf *compute.BaremetalDiskConfig) error
BuildRaid5(devs []*baremetal.BaremetalStorage, conf *compute.BaremetalDiskConfig) error
BuildRaid10(devs []*baremetal.BaremetalStorage, conf *compute.BaremetalDiskConfig) error
BuildNoneRaid(devs []*baremetal.BaremetalStorage) error
}
type sRaid struct {
driver iDriver
term raid.IExecTerm
adaptors []*sRaidAdaptor
phyDevsCnt int
}
func newRaid(term raid.IExecTerm) raid.IRaidDriver {
perccliDrv := &sRaid{
driver: newPerccliDriver(),
term: term,
adaptors: make([]*sRaidAdaptor, 0),
}
if err := perccliDrv.ParsePhyDevs(); err == nil && perccliDrv.phyDevsCnt > 0 {
log.Infof("Use perccli driver, found %d pds", perccliDrv.phyDevsCnt)
return perccliDrv
} else {
log.Warningf("perccli driver parse physical devices error: %v, %d pds, fallback to old megactl and storcli driver", err, perccliDrv.phyDevsCnt)
return NewMegaRaid(term)
}
}
func (r *sRaid) GetName() string {
return baremetal.DISK_DRIVER_MEGARAID
}
type sRaidAdaptor struct {
iAdaptor
raid *sRaid
devs []*MegaRaidPhyDev
sn string
name string
busNumber string
deviceNumber string
funcNumber string
// used by sg_map
hostNum int
//channelNum int
}
func newRaidAdaptor(baseAda iAdaptor, raid *sRaid) *sRaidAdaptor {
return &sRaidAdaptor{
iAdaptor: baseAda,
raid: raid,
devs: make([]*MegaRaidPhyDev, 0),
}
}
func (a *sRaidAdaptor) AddPhyDev(dev *MegaRaidPhyDev) {
a.devs = append(a.devs, dev)
}
func (r *sRaid) ParsePhyDevs() error {
adaptors, _, err := r.getAdaptor()
r.phyDevsCnt = 0
if err != nil {
return errors.Wrapf(err, "Get %q adaptor", r.driver.GetName())
}
r.adaptors = make([]*sRaidAdaptor, 0)
for _, ada := range adaptors {
devs, err := ada.GetPhyDevs()
if err != nil {
return errors.Wrap(err, "Get %q adaptor physical devices")
}
nAda := newRaidAdaptor(ada, r)
for i := range devs {
nAda.AddPhyDev(devs[i])
r.phyDevsCnt++
}
r.adaptors = append(r.adaptors, nAda)
}
return nil
}
func (r *sRaid) getAdaptor() ([]iAdaptor, map[string]iAdaptor, error) {
ret := make(map[string]iAdaptor)
cmd := r.driver.GetAdapterConstructCmd()
lines, err := r.term.Run(cmd)
if err != nil {
return nil, nil, errors.Wrap(err, "Get storcli adapter")
}
adaptor := r.driver.NewAdaptor(r.term)
list := make([]iAdaptor, 0)
for _, l := range lines {
adaptor.ParseLine(l)
if adaptor.IsComplete() {
ret[adaptor.Key()] = adaptor
list = append(list, adaptor)
adaptor = r.driver.NewAdaptor(r.term)
}
}
return list, ret, nil
}
func (r *sRaid) PreBuildRaid(_ []*compute.BaremetalDiskConfig, _ int) error {
return r.driver.ClearForeignState(r.term)
}
func (r *sRaid) GetAdapters() []raid.IRaidAdapter {
ret := make([]raid.IRaidAdapter, len(r.adaptors))
for i := range r.adaptors {
ret[i] = r.adaptors[i]
}
return ret
}
func (r *sRaidAdaptor) PreBuildRaid(_ []*compute.BaremetalDiskConfig) error {
r.ClearJBODDisks()
return nil
}
func (r *sRaidAdaptor) ClearJBODDisks() {
r.iAdaptor.ClearJBODDisks(r.devs)
}
func (r *sRaidAdaptor) GetDevices() []*baremetal.BaremetalStorage {
ret := []*baremetal.BaremetalStorage{}
for idx, dev := range r.devs {
ret = append(ret, dev.ToBaremetalStorage(idx))
}
return ret
}
func (r *sRaid) CleanRaid() error {
for _, ada := range r.adaptors {
ada.ClearJBODDisks()
ada.RemoveLogicVolumes()
}
return nil
}
+227
View File
@@ -0,0 +1,227 @@
// 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 (
"fmt"
"strings"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/baremetal/utils/raid"
"yunion.io/x/onecloud/pkg/compute/baremetal"
)
func storcliIsJBODEnabled(
getCmd func(args ...string) (string, error),
term raid.IExecTerm,
) bool {
cmd, err := getCmd("show", "jbod")
if err != nil {
log.Errorf("get storcli controller cmd: %v", err)
return false
}
lines, err := term.Run(cmd)
if err != nil {
log.Errorf("storcliIsJBODEnabled error: %s", err)
return false
}
for _, line := range lines {
line = strings.ToLower(line)
if strings.HasPrefix(line, "jbod") {
data := strings.Split(line, " ")
if strings.TrimSpace(data[len(data)-1]) == "on" {
return true
}
return false
}
}
return false
}
func storcliEnableJBOD(
getCmd func(args ...string) (string, error),
term raid.IExecTerm,
enable bool) bool {
val := "off"
if enable {
val = "on"
}
cmd, err := getCmd("set", fmt.Sprintf("jbod=%s", val), "force")
if err != nil {
log.Errorf("get storcli controller cmd: %v", err)
return false
}
_, err = term.Run(cmd)
if err != nil {
log.Errorf("EnableJBOD %v fail: %v", enable, err)
return false
}
return true
}
func storcliBuildJBOD(
getCmd func(args ...string) (string, error),
term raid.IExecTerm,
devs []*baremetal.BaremetalStorage) error {
if !storcliIsJBODEnabled(getCmd, term) {
storcliEnableJBOD(getCmd, term, true)
storcliEnableJBOD(getCmd, term, false)
storcliEnableJBOD(getCmd, term, true)
}
if !storcliIsJBODEnabled(getCmd, term) {
return fmt.Errorf("JBOD not supported")
}
cmds := []string{}
for _, d := range devs {
// cmd := GetCommand2(fmt.Sprintf("/c%d/e%d/s%d", adapter.storcliIndex, d.Enclosure, d.Slot))
cmd, err := getCmd()
if err != nil {
return errors.Wrapf(err, "getCmd for dev %#v", d)
}
cmd = fmt.Sprintf("%s/e%d/s%d", d.Enclosure, d.Slot)
cmds = append(cmds, cmd)
}
log.Infof("storcliBuildJBOD cmds: %v", cmds)
_, err := term.Run(cmds...)
if err != nil {
return err
}
return nil
}
func storcliBuildNoRaid(
getCmd func(args ...string) (string, error),
term raid.IExecTerm,
devs []*baremetal.BaremetalStorage) error {
err := storcliBuildJBOD(getCmd, term, devs)
if err == nil {
return nil
}
log.Errorf("Try storcli build JBOD fail: %v", err)
labels := []string{}
for _, dev := range devs {
labels = append(labels, GetSpecString(dev))
}
args := []string{
"add", "vd", "each", "type=raid0",
fmt.Sprintf("drives=%s", strings.Join(labels, ",")),
"wt", "nora", "direct",
}
cmd, err := getCmd(args...)
if err != nil {
return errors.Wrapf(err, "build none raid")
}
_, err = term.Run(cmd)
return err
}
func storcliClearJBODDisks(
getCmd func(args ...string) (string, error),
term raid.IExecTerm,
devs []*MegaRaidPhyDev,
) error {
errs := make([]error, 0)
for _, dev := range devs {
cmd, err := getCmd()
if err != nil {
return errors.Wrap(err, "get cmd error")
}
cmd = fmt.Sprintf("%s/e%d/s%d set good force", cmd, dev.enclosure, dev.slot)
if _, err := term.Run(cmd); err != nil {
err = errors.Wrapf(err, "Set PD good storcli cmd %v", cmd)
errs = append(errs, err)
}
}
return errors.NewAggregate(errs)
}
func storcliBuildRaid(
getCmd func(args ...string) (string, error),
term raid.IExecTerm,
devs []*baremetal.BaremetalStorage,
conf *api.BaremetalDiskConfig,
level uint,
) error {
args := []string{}
args = append(args, "add", "vd", fmt.Sprintf("type=r%d", level))
args = append(args, conf2ParamsStorcliSize(conf)...)
labels := []string{}
for _, dev := range devs {
labels = append(labels, GetSpecString(dev))
}
args = append(args, fmt.Sprintf("drives=%s", strings.Join(labels, ",")))
if level == 10 {
args = append(args, "PDperArray=2")
}
args = append(args, conf2ParamsStorcli(conf)...)
cmd, err := getCmd(args...)
if err != nil {
return errors.Wrapf(err, "build raid %d", level)
}
log.Infof("_storcliBuildRaid command: %s", cmd)
_, err = term.Run(cmd)
return err
}
func conf2ParamsStorcliSize(conf *api.BaremetalDiskConfig) []string {
params := []string{}
szStr := []string{}
if len(conf.Size) > 0 {
for _, sz := range conf.Size {
szStr = append(szStr, fmt.Sprintf("%dMB", sz))
}
params = append(params, fmt.Sprintf("Size=%s", strings.Join(szStr, ",")))
}
return params
}
func conf2ParamsStorcli(conf *api.BaremetalDiskConfig) []string {
params := []string{}
if conf.WT != nil {
if *conf.WT {
params = append(params, "wt")
} else {
params = append(params, "wb")
}
}
if conf.RA != nil {
if *conf.RA {
params = append(params, "ra")
} else {
params = append(params, "nora")
}
}
if conf.Direct != nil {
if *conf.Direct {
params = append(params, "direct")
} else {
params = append(params, "cached")
}
}
if conf.Cachedbadbbu != nil {
if *conf.Cachedbadbbu {
params = append(params, "CachedBadBBU")
} else {
params = append(params, "NoCachedBadBBU")
}
}
if conf.Strip != nil {
params = append(params, fmt.Sprintf("Strip=%d", *conf.Strip))
}
return params
}
+18 -146
View File
@@ -543,54 +543,6 @@ func (adapter *MegaRaidAdaptor) PreBuildRaid(confs []*api.BaremetalDiskConfig) e
return nil
}
func (adapter *MegaRaidAdaptor) conf2ParamsStorcliSize(conf *api.BaremetalDiskConfig) []string {
params := []string{}
szStr := []string{}
if len(conf.Size) > 0 {
for _, sz := range conf.Size {
szStr = append(szStr, fmt.Sprintf("%dMB", sz))
}
params = append(params, fmt.Sprintf("Size=%s", strings.Join(szStr, ",")))
}
return params
}
func (adapter *MegaRaidAdaptor) conf2ParamsStorcli(conf *api.BaremetalDiskConfig) []string {
params := []string{}
if conf.WT != nil {
if *conf.WT {
params = append(params, "wt")
} else {
params = append(params, "wb")
}
}
if conf.RA != nil {
if *conf.RA {
params = append(params, "ra")
} else {
params = append(params, "nora")
}
}
if conf.Direct != nil {
if *conf.Direct {
params = append(params, "direct")
} else {
params = append(params, "cached")
}
}
if conf.Cachedbadbbu != nil {
if *conf.Cachedbadbbu {
params = append(params, "CachedBadBBU")
} else {
params = append(params, "NoCachedBadBBU")
}
}
if conf.Strip != nil {
params = append(params, fmt.Sprintf("Strip=%d", *conf.Strip))
}
return params
}
func conf2Params(conf *api.BaremetalDiskConfig) []string {
params := []string{}
if conf.WT != nil {
@@ -681,25 +633,10 @@ func (adapter *MegaRaidAdaptor) megacliBuildRaid10(devs []*baremetal.BaremetalSt
}
func (adapter *MegaRaidAdaptor) storcliBuildRaid(devs []*baremetal.BaremetalStorage, conf *api.BaremetalDiskConfig, level uint) error {
args := []string{}
args = append(args, "add", "vd", fmt.Sprintf("type=r%d", level))
args = append(args, adapter.conf2ParamsStorcliSize(conf)...)
labels := []string{}
for _, dev := range devs {
labels = append(labels, GetSpecString(dev))
}
args = append(args, fmt.Sprintf("drives=%s", strings.Join(labels, ",")))
if level == 10 {
args = append(args, "PDperArray=2")
}
args = append(args, adapter.conf2ParamsStorcli(conf)...)
cmd, err := adapter.GetStorcliCommand(args...)
if err != nil {
return errors.Wrapf(err, "build raid %d", level)
}
log.Infof("_storcliBuildRaid command: %s", cmd)
_, err = adapter.remoteRun(cmd)
return err
return storcliBuildRaid(
adapter.GetStorcliCommand,
adapter.getTerm(),
devs, conf, level)
}
func (adapter *MegaRaidAdaptor) megacliBuildRaid(devs []*baremetal.BaremetalStorage, conf *api.BaremetalDiskConfig, level uint) error {
@@ -897,9 +834,10 @@ func parseStorcliControllers(jsonStr string) (*StorcliControllersInfo, error) {
return info, nil
}
func (a *StorcliAdaptor) getPhyDevs(raid *MegaRaid) ([]*StorcliPhysicalDrive, error) {
cmd := GetCommand2(fmt.Sprintf("/c%d/eall/sall show J", a.Controller))
lines, err := raid.term.Run(cmd)
func (a *StorcliAdaptor) getPhyDevs(getCmd func(...string) string, term raid.IExecTerm) ([]*StorcliPhysicalDrive, error) {
cmd := getCmd(fmt.Sprintf("/c%d/eall/sall show J", a.Controller))
log.Errorf("----term %#v, cmd: %q", term, cmd)
lines, err := term.Run(cmd)
if err != nil {
return nil, errors.Wrap(err, "Get storcli PDList json output")
}
@@ -914,8 +852,8 @@ func (a *StorcliAdaptor) getPhyDevs(raid *MegaRaid) ([]*StorcliPhysicalDrive, er
return info.Controllers[0].ResponseData.Info, nil
}
func (a *StorcliAdaptor) getMegaPhyDevs(raid *MegaRaid) ([]*MegaRaidPhyDev, error) {
pdList, err := a.getPhyDevs(raid)
func (a *StorcliAdaptor) getMegaPhyDevs(getCmd func(...string) string, term raid.IExecTerm) ([]*MegaRaidPhyDev, error) {
pdList, err := a.getPhyDevs(getCmd, term)
if err != nil {
return nil, errors.Wrap(err, "storcli getPhyDevs")
}
@@ -976,27 +914,7 @@ func (adapter *MegaRaidAdaptor) GetStorcliCommand(args ...string) (string, error
}
func (adapter *MegaRaidAdaptor) storcliIsJBODEnabled() bool {
cmd, err := adapter.GetStorcliCommand("show", "jbod")
if err != nil {
log.Errorf("get storcli controller cmd: %v", err)
return false
}
lines, err := adapter.remoteRun(cmd)
if err != nil {
log.Errorf("storcliIsJBODEnabled error: %s", err)
return false
}
for _, line := range lines {
line = strings.ToLower(line)
if strings.HasPrefix(line, "jbod") {
data := strings.Split(line, " ")
if strings.TrimSpace(data[len(data)-1]) == "on" {
return true
}
return false
}
}
return false
return storcliIsJBODEnabled(adapter.GetStorcliCommand, adapter.getTerm())
}
func (adapter *MegaRaidAdaptor) storcliEnableJBOD(enable bool) bool {
@@ -1018,48 +936,11 @@ func (adapter *MegaRaidAdaptor) storcliEnableJBOD(enable bool) bool {
}
func (adapter *MegaRaidAdaptor) storcliBuildJBOD(devs []*baremetal.BaremetalStorage) error {
if !adapter.storcliIsJBODEnabled() {
adapter.storcliEnableJBOD(true)
adapter.storcliEnableJBOD(false)
adapter.storcliEnableJBOD(true)
}
if !adapter.storcliIsJBODEnabled() {
return fmt.Errorf("JBOD not supported")
}
cmds := []string{}
for _, d := range devs {
cmd := GetCommand2(fmt.Sprintf("/c%d/e%d/s%d", adapter.storcliIndex, d.Enclosure, d.Slot))
cmds = append(cmds, cmd)
}
log.Infof("storcliBuildJBOD cmds: %v", cmds)
_, err := adapter.remoteRun(cmds...)
if err != nil {
return err
}
return nil
return storcliBuildJBOD(adapter.GetStorcliCommand, adapter.getTerm(), devs)
}
func (adapter *MegaRaidAdaptor) storcliBuildNoRaid(devs []*baremetal.BaremetalStorage, _ *api.BaremetalDiskConfig) error {
err := adapter.storcliBuildJBOD(devs)
if err == nil {
return nil
}
log.Errorf("Try storcli build JBOD fail: %v", err)
labels := []string{}
for _, dev := range devs {
labels = append(labels, GetSpecString(dev))
}
args := []string{
"add", "vd", "each", "type=raid0",
fmt.Sprintf("drives=%s", strings.Join(labels, ",")),
"wt", "nora", "direct",
}
cmd, err := adapter.GetStorcliCommand(args...)
if err != nil {
return errors.Wrapf(err, "build none raid")
}
_, err = adapter.remoteRun(cmd)
return err
return storcliBuildNoRaid(adapter.GetStorcliCommand, adapter.getTerm(), devs)
}
func (adapter *MegaRaidAdaptor) megacliBuildNoRaid(devs []*baremetal.BaremetalStorage, _ *api.BaremetalDiskConfig) error {
@@ -1152,15 +1033,10 @@ func (adapter *MegaRaidAdaptor) RemoveLogicVolumes() error {
}
func (adapter *MegaRaidAdaptor) storcliClearJBODDisks() error {
errs := make([]error, 0)
for _, dev := range adapter.devs {
cmd := GetCommand2(fmt.Sprintf("/c%d/e%d/s%d", adapter.index, dev.enclosure, dev.slot), "set", "good", "force")
if _, err := adapter.remoteRun(cmd); err != nil {
err = errors.Wrapf(err, "Set PD good storcli cmd %v", cmd)
errs = append(errs, err)
}
}
return errors.NewAggregate(errs)
return storcliClearJBODDisks(
adapter.GetStorcliCommand, adapter.getTerm(),
adapter.devs,
)
}
func (adapter *MegaRaidAdaptor) megacliClearJBODDisks() error {
@@ -1263,7 +1139,7 @@ func (raid *MegaRaid) parsePhyDevsUseStorcli() error {
if err != nil {
return errors.Wrap(err, "NewMegaRaidAdaptorByStorcli")
}
devs, err := ada.getMegaPhyDevs(raid)
devs, err := ada.getMegaPhyDevs(GetCommand2, raid.term)
if err != nil {
return errors.Wrapf(err, "get storcli %d mega PDs", ada.Controller)
}
@@ -1364,7 +1240,3 @@ func (raid *MegaRaid) RemoveLogicVolumes() {
adapter.RemoveLogicVolumes()
}
}
func init() {
raiddrivers.RegisterDriver(baremetal.DISK_DRIVER_MEGARAID, NewMegaRaid)
}
+169
View File
@@ -0,0 +1,169 @@
// 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 (
"fmt"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/baremetal/utils/raid"
"yunion.io/x/onecloud/pkg/compute/baremetal"
)
var (
_ iDriver = new(perccliDriver)
)
type perccliDriver struct{}
func newPerccliDriver() iDriver {
return new(perccliDriver)
}
func (_ *perccliDriver) GetName() string {
return "MegaRAID_Perccli"
}
func (_ *perccliDriver) GetAdapterConstructCmd() string {
return getPerccliCmd("/call", "show", "|", "grep", "-iE", `'^(Controller|Product Name|Serial Number|Bus Number|Device Number|Function Number)\s='`)
}
func (_ *perccliDriver) NewAdaptor(term raid.IExecTerm) iAdaptor {
return newPerccliAdaptor(term)
}
func (_ *perccliDriver) ClearForeignState(term raid.IExecTerm) error {
cmd := getPerccliCmd("/call/fall", "delete")
if _, err := term.Run(cmd); err != nil {
return err
}
return nil
}
func getPerccliCmd(args ...string) string {
bin := "/opt/MegaRAID/perccli/perccli"
return raid.GetCommand(bin, args...)
}
type PerccliAdaptor struct {
*StorcliAdaptor
term raid.IExecTerm
}
func newPerccliAdaptor(term raid.IExecTerm) *PerccliAdaptor {
return &PerccliAdaptor{
StorcliAdaptor: newStorcliAdaptor(),
term: term,
}
}
func (a *PerccliAdaptor) ParseLine(line string) {
a.StorcliAdaptor.parseLine(line)
}
func (a *PerccliAdaptor) IsComplete() bool {
return a.isComplete()
}
func (a *PerccliAdaptor) Key() string {
return a.key()
}
func (a *PerccliAdaptor) GetPhyDevs() ([]*MegaRaidPhyDev, error) {
return a.getMegaPhyDevs(a.getCmd, a.term)
}
func (a *PerccliAdaptor) ClearJBODDisks(devs []*MegaRaidPhyDev) {
storcliClearJBODDisks(a.getAdaptorCmd, a.term, devs)
}
func (a *PerccliAdaptor) GetIndex() int {
return a.Controller
}
func (a *PerccliAdaptor) getCmd(args ...string) string {
return getPerccliCmd(args...)
}
func (a *PerccliAdaptor) getAdaptorCmd(args ...string) (string, error) {
nargs := []string{fmt.Sprintf("/c%d", a.GetIndex())}
nargs = append(nargs, args...)
return a.getCmd(nargs...), nil
}
func (a *PerccliAdaptor) GetLogicVolumes() ([]*raid.RaidLogicalVolume, error) {
cmd := a.getCmd(fmt.Sprintf("/c%d/vall", a.GetIndex()), "show")
ret, err := a.term.Run(cmd)
if err != nil {
return nil, errors.Wrap(err, "Get perccli logical volumes")
}
return parseStorcliLogicalVolumes(a.GetIndex(), ret)
}
func (a *PerccliAdaptor) RemoveLogicVolumes() error {
lvIdx, err := a.GetLogicVolumes()
if err != nil {
return errors.Wrap(err, "GetLogicVolumes")
}
for _, i := range raid.ReverseLogicalArray(lvIdx) {
cmd := a.getCmd(fmt.Sprintf("/c%d/v%d", a.GetIndex(), i.Index), "delete", "force")
if _, err := a.term.Run(cmd); err != nil {
return errors.Wrapf(err, "remove adaptor %d lv %d", a.GetIndex(), i.Index)
}
}
return nil
}
func (a *PerccliAdaptor) BuildRaid0(devs []*baremetal.BaremetalStorage, conf *compute.BaremetalDiskConfig) error {
return cliBuildRaid(devs, conf, func(bs []*baremetal.BaremetalStorage, bdc *compute.BaremetalDiskConfig) error {
return storcliBuildRaid(a.getAdaptorCmd, a.term, devs, conf, 0)
})
}
func (a *PerccliAdaptor) BuildRaid1(devs []*baremetal.BaremetalStorage, conf *compute.BaremetalDiskConfig) error {
return cliBuildRaid(devs, conf, func(bs []*baremetal.BaremetalStorage, bdc *compute.BaremetalDiskConfig) error {
return storcliBuildRaid(a.getAdaptorCmd, a.term, devs, conf, 1)
})
}
func (a *PerccliAdaptor) BuildRaid5(devs []*baremetal.BaremetalStorage, conf *compute.BaremetalDiskConfig) error {
return cliBuildRaid(devs, conf, func(bs []*baremetal.BaremetalStorage, bdc *compute.BaremetalDiskConfig) error {
return storcliBuildRaid(a.getAdaptorCmd, a.term, devs, conf, 5)
})
}
func (a *PerccliAdaptor) BuildRaid10(devs []*baremetal.BaremetalStorage, conf *compute.BaremetalDiskConfig) error {
return cliBuildRaid(devs, conf, func(bs []*baremetal.BaremetalStorage, bdc *compute.BaremetalDiskConfig) error {
return storcliBuildRaid(a.getAdaptorCmd, a.term, devs, conf, 10)
})
}
func (a *PerccliAdaptor) BuildNoneRaid(devs []*baremetal.BaremetalStorage) error {
return cliBuildRaid(devs, nil, func(bs []*baremetal.BaremetalStorage, bdc *compute.BaremetalDiskConfig) error {
return storcliBuildNoRaid(a.getAdaptorCmd, a.term, devs)
})
}
type PerccliPhyDev struct {
*StorcliPhysicalDrive
}
func NewPerccliPhyDev(base *StorcliPhysicalDrive) *PerccliPhyDev {
return &PerccliPhyDev{
StorcliPhysicalDrive: base,
}
}