diff --git a/pkg/baremetal/utils/raid/drivers/drivers.go b/pkg/baremetal/utils/raid/drivers/drivers.go index 746c02a282..4237aa04f8 100644 --- a/pkg/baremetal/utils/raid/drivers/drivers.go +++ b/pkg/baremetal/utils/raid/drivers/drivers.go @@ -116,12 +116,13 @@ func buildRaid(driver raid.IRaidDriver, adapter raid.IRaidAdapter, confs []*api. var selected []*baremetal.BaremetalStorage var nonDisks []*baremetal.BaremetalStorage + var err error left := devs for _, conf := range confs { - selected, left = baremetal.RetrieveStorages(conf, left) + selected, left, err = baremetal.RetrieveStorages(conf, left) if len(selected) == 0 { - return fmt.Errorf("No enough disks for config %#v", conf) + return errors.Wrapf(err, "no enough disks for config %#v", conf) } var err error switch conf.Conf { diff --git a/pkg/compute/baremetal/diskconfig.go b/pkg/compute/baremetal/diskconfig.go index 9897ae599b..b1a9f89537 100644 --- a/pkg/compute/baremetal/diskconfig.go +++ b/pkg/compute/baremetal/diskconfig.go @@ -45,7 +45,7 @@ func isDiskConfigStorageMatch( confAdapter *int, storage *BaremetalStorage, selected []*BaremetalStorage, -) bool { +) (bool, error) { isRotate := storage.Rotate adapter := storage.Adapter index := storage.Index @@ -60,17 +60,26 @@ func isDiskConfigStorageMatch( adapterIsEqual := (confAdapter == nil || *confAdapter == adapter) && (confDriver == nil || *confDriver == driver) - log.V(10).Debugf("Try storage: %#v, typeIsHybrid: %v, typeIsRotate: %v, typeIsSSD: %v, rangeIsNoneAndCountZero: %v, rangeIsNotNoneAndIndexInRange: %v, rangeIsNoneAndSmallThanCount: %v, adapterIsEqual: %v", *storage, typeIsHybrid, typeIsRotate, typeIsSSD, rangeIsNoneAndCountZero, rangeIsNotNoneAndIndexInRange, rangeIsNoneAndSmallThanCount, adapterIsEqual) - if (typeIsHybrid || typeIsRotate || typeIsSSD) && (rangeIsNoneAndCountZero || rangeIsNotNoneAndIndexInRange || rangeIsNoneAndSmallThanCount) && adapterIsEqual { - return true + return true, nil } - return false + errs := []error{} + // aggregate errors + if !(typeIsHybrid || typeIsRotate || typeIsSSD) { + errs = append(errs, fmt.Errorf("check type: is_hybrid: %v, is_rotate: %v, is_ssd: %v, type: %s", typeIsHybrid, typeIsRotate, typeIsSSD, config.Type)) + } + if !(rangeIsNoneAndCountZero || rangeIsNotNoneAndIndexInRange || rangeIsNoneAndSmallThanCount) { + errs = append(errs, fmt.Errorf("check range: is_none: %v, index_in_range: %v, small_than_count: %v, index: %d, range: %v", rangeIsNoneAndCountZero, rangeIsNotNoneAndIndexInRange, rangeIsNoneAndSmallThanCount, index, config.Range)) + } + if adapterIsEqual { + errs = append(errs, fmt.Errorf("check adapter: is_equal: %v", adapterIsEqual)) + } + return false, errors.NewAggregate(errs) } -func RetrieveStorages(diskConfig *api.BaremetalDiskConfig, storages []*BaremetalStorage) (selected, rest []*BaremetalStorage) { +func RetrieveStorages(diskConfig *api.BaremetalDiskConfig, storages []*BaremetalStorage) (selected, rest []*BaremetalStorage, err error) { var confDriver *string = nil var confAdapter *int = nil @@ -83,24 +92,36 @@ func RetrieveStorages(diskConfig *api.BaremetalDiskConfig, storages []*Baremetal selected = make([]*BaremetalStorage, 0) rest = make([]*BaremetalStorage, 0) + errs := []error{} + idx := 0 curAdapter := 0 adapterChange := false + curDriver := "" + driverChange := false for _, storage := range storages { if storage.Adapter != curAdapter { adapterChange = true curAdapter = storage.Adapter } + if storage.Driver != curDriver { + driverChange = true + curDriver = storage.Driver + } if adapterChange { idx = 0 adapterChange = false } + if driverChange { + idx = 0 + driverChange = false + } if storage.Index == 0 { storage.Index = int64(idx) } - if isDiskConfigStorageMatch(diskConfig, confDriver, confAdapter, storage, selected) { + if isMatched, mErr := isDiskConfigStorageMatch(diskConfig, confDriver, confAdapter, storage, selected); isMatched { if confDriver == nil { confDriver = &storage.Driver } @@ -110,6 +131,7 @@ func RetrieveStorages(diskConfig *api.BaremetalDiskConfig, storages []*Baremetal selected = append(selected, storage) } else { rest = append(rest, storage) + errs = append(errs, mErr) } if confDriver == nil { idx++ @@ -117,6 +139,9 @@ func RetrieveStorages(diskConfig *api.BaremetalDiskConfig, storages []*Baremetal idx++ } } + if len(errs) > 0 { + err = errors.NewAggregate(errs) + } return } @@ -349,10 +374,10 @@ func CalculateLayout(confs []*api.BaremetalDiskConfig, storages []*BaremetalStor noneConf, _ := ParseDiskConfig(DISK_CONF_NONE) conf = &noneConf } - selected, restStorges := RetrieveStorages(conf, storages) + selected, restStorges, rErr := RetrieveStorages(conf, storages) storages = restStorges if len(selected) == 0 { - err = fmt.Errorf("Not found matched storages by config: %#v", conf) + err = errors.Wrapf(rErr, "not found matched storages by config: %#v", conf) return } resultErr := MeetConfig(conf, selected) diff --git a/pkg/compute/baremetal/diskconfig_test.go b/pkg/compute/baremetal/diskconfig_test.go index 5b796f17a3..2e1f514a0a 100644 --- a/pkg/compute/baremetal/diskconfig_test.go +++ b/pkg/compute/baremetal/diskconfig_test.go @@ -476,6 +476,278 @@ func TestCalculateLayout(t *testing.T) { } } +func TestCalculateLayout2(t *testing.T) { + adapater0 := 0 + confs := []*api.BaremetalDiskConfig{ + { + Adapter: &adapater0, + Conf: DISK_CONF_RAID1, + Count: 2, + Driver: DISK_DRIVER_MEGARAID, + Range: []int64{12, 13}, + Type: DISK_TYPE_ROTATE, + }, + { + Adapter: &adapater0, + Conf: DISK_CONF_RAID10, + Count: 12, + Driver: DISK_DRIVER_MEGARAID, + Range: []int64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, + Type: DISK_TYPE_ROTATE, + }, + { + Adapter: &adapater0, + Conf: DISK_CONF_NONE, + Count: 1, + Driver: DISK_DRIVER_PCIE, + Range: []int64{0}, + Type: DISK_TYPE_SSD, + }, + } + storages := []*BaremetalStorage{} + storageJson := `[ + { + "adapter": 0, + "block": 512, + "driver": "MegaRaid", + "enclousure": 65, + "index": 0, + "max_strip_size": 0, + "min_strip_size": 0, + "model": "HGST HUS728T8TAL5200 A9Y2VY1A1JPM", + "rotate": true, + "sector": 15626993664, + "size": 7630368, + "slot": 0, + "status": "unconfigured_good" + }, + { + "adapter": 0, + "block": 512, + "driver": "MegaRaid", + "enclousure": 65, + "index": 0, + "max_strip_size": 0, + "min_strip_size": 0, + "model": "HGST HUS728T8TAL5200 A9Y2VY1AMGGM", + "rotate": true, + "sector": 15626993664, + "size": 7630368, + "slot": 1, + "status": "unconfigured_good" + }, + { + "adapter": 0, + "block": 512, + "driver": "MegaRaid", + "enclousure": 65, + "index": 0, + "max_strip_size": 0, + "min_strip_size": 0, + "model": "HGST HUS728T8TAL5200 A9Y2VY1AN53M", + "rotate": true, + "sector": 15626993664, + "size": 7630368, + "slot": 2, + "status": "unconfigured_good" + }, + { + "adapter": 0, + "block": 512, + "driver": "MegaRaid", + "enclousure": 65, + "index": 0, + "max_strip_size": 0, + "min_strip_size": 0, + "model": "HGST HUS728T8TAL5200 A9Y2VY1ATVBM", + "rotate": true, + "sector": 15626993664, + "size": 7630368, + "slot": 3, + "status": "unconfigured_good" + }, + { + "adapter": 0, + "block": 512, + "driver": "MegaRaid", + "enclousure": 65, + "index": 0, + "max_strip_size": 0, + "min_strip_size": 0, + "model": "HGST HUS728T8TAL5200 A9Y2VY1AR4VM", + "rotate": true, + "sector": 15626993664, + "size": 7630368, + "slot": 4, + "status": "unconfigured_good" + }, + { + "adapter": 0, + "block": 512, + "driver": "MegaRaid", + "enclousure": 65, + "index": 0, + "max_strip_size": 0, + "min_strip_size": 0, + "model": "HGST HUS728T8TAL5200 A9Y2VY1ARYBM", + "rotate": true, + "sector": 15626993664, + "size": 7630368, + "slot": 5, + "status": "unconfigured_good" + }, + { + "adapter": 0, + "block": 512, + "driver": "MegaRaid", + "enclousure": 65, + "index": 0, + "max_strip_size": 0, + "min_strip_size": 0, + "model": "HGST HUS728T8TAL5200 A9Y2VY1AS36M", + "rotate": true, + "sector": 15626993664, + "size": 7630368, + "slot": 6, + "status": "unconfigured_good" + }, + { + "adapter": 0, + "block": 512, + "driver": "MegaRaid", + "enclousure": 65, + "index": 0, + "max_strip_size": 0, + "min_strip_size": 0, + "model": "HGST HUS728T8TAL5200 A9Y2VY1A1K6M", + "rotate": true, + "sector": 15626993664, + "size": 7630368, + "slot": 7, + "status": "unconfigured_good" + }, + { + "adapter": 0, + "block": 512, + "driver": "MegaRaid", + "enclousure": 65, + "index": 0, + "max_strip_size": 0, + "min_strip_size": 0, + "model": "HGST HUS728T8TAL5200 A9Y2VY1AM98M", + "rotate": true, + "sector": 15626993664, + "size": 7630368, + "slot": 8, + "status": "unconfigured_good" + }, + { + "adapter": 0, + "block": 512, + "driver": "MegaRaid", + "enclousure": 65, + "index": 0, + "max_strip_size": 0, + "min_strip_size": 0, + "model": "HGST HUS728T8TAL5200 A9Y2VY1ATTLM", + "rotate": true, + "sector": 15626993664, + "size": 7630368, + "slot": 9, + "status": "unconfigured_good" + }, + { + "adapter": 0, + "block": 512, + "driver": "MegaRaid", + "enclousure": 65, + "index": 0, + "max_strip_size": 0, + "min_strip_size": 0, + "model": "HGST HUS728T8TAL5200 A9Y2VY1AR3DM", + "rotate": true, + "sector": 15626993664, + "size": 7630368, + "slot": 10, + "status": "unconfigured_good" + }, + { + "adapter": 0, + "block": 512, + "driver": "MegaRaid", + "enclousure": 65, + "index": 0, + "max_strip_size": 0, + "min_strip_size": 0, + "model": "HGST HUS728T8TAL5200 A9Y2VY1AN3DM", + "rotate": true, + "sector": 15626993664, + "size": 7630368, + "slot": 11, + "status": "unconfigured_good" + }, + { + "adapter": 0, + "block": 512, + "driver": "MegaRaid", + "enclousure": 65, + "index": 0, + "max_strip_size": 0, + "min_strip_size": 0, + "model": "TOSHIBA AL15SEB060N 310253K0A07BFYVH", + "rotate": true, + "sector": 1171062784, + "size": 571808, + "slot": 12, + "status": "online" + }, + { + "adapter": 0, + "block": 512, + "driver": "MegaRaid", + "enclousure": 65, + "index": 0, + "max_strip_size": 0, + "min_strip_size": 0, + "model": "TOSHIBA AL15SEB060N 310253K0A0EDFYVH", + "rotate": true, + "sector": 1171062784, + "size": 571808, + "slot": 13, + "status": "online" + }, + { + "adapter": 0, + "block": 512, + "dev": "nvme0n1", + "driver": "", + "enclousure": 0, + "index": 0, + "kernel": "unknown", + "max_strip_size": 0, + "min_strip_size": 0, + "module": "INSPUR-NS8600G2U640", + "pci_class": "unknown", + "rotate": false, + "sector": 12502446768, + "size": 6104710, + "slot": 0 + } +]` + storageObj, err := jsonutils.ParseString(storageJson) + if err != nil { + t.Fatalf("parse json error: %v", err) + } + if err := storageObj.Unmarshal(&storages); err != nil { + t.Fatalf("unmarshal json to storages: %v", err) + } + layout, err := CalculateLayout(confs, storages) + if err != nil { + t.Fatalf("calculate layout: %v", err) + } + log.Infof("layout: %+v", layout) +} + func TestCheckDisksAllocable(t *testing.T) { confs, err := NewBaremetalDiskConfigs( "[0-1]:raid1:(100g,32g,):adapter0", @@ -1211,12 +1483,12 @@ func TestRetrieveStorages(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - gotSelected, gotRest := RetrieveStorages(tt.args.diskConfig, tt.args.storages) + gotSelected, gotRest, err := RetrieveStorages(tt.args.diskConfig, tt.args.storages) if !reflect.DeepEqual(gotSelected, tt.wantSelected) { - t.Errorf("RetrieveStorages() gotSelected = %v, want %v", gotSelected, tt.wantSelected) + t.Errorf("RetrieveStorages() gotSelected = %v, want %v, err: %s", gotSelected, tt.wantSelected, err) } if !reflect.DeepEqual(gotRest, tt.wantRest) { - t.Errorf("RetrieveStorages() gotRest = %v, want %v", gotRest, tt.wantRest) + t.Errorf("RetrieveStorages() gotRest = %v, want %v, err: %s", gotRest, tt.wantRest, err) } }) }