Merge pull request #6103 from ioito/bugfix/qx-openstack-storage-sync

fix: 修复openstack存储同步问题
This commit is contained in:
yunion-ci-robot
2020-04-28 23:35:34 +08:00
committed by GitHub
4 changed files with 111 additions and 24 deletions
+8 -21
View File
@@ -17,7 +17,6 @@ package openstack
import (
"fmt"
"strconv"
"strings"
"time"
"github.com/pkg/errors"
@@ -121,25 +120,13 @@ func (host *SHost) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
return nil, err
}
schedulerPools, err := host.zone.getSchedulerStatsPool()
if err != nil {
return nil, err
}
storageTypes := host.zone.getAvailableStorages()
storageTypes = append(storageTypes, host.zone.getUnavailableStorage()...)
result := []cloudprovider.ICloudStorage{}
for _, istorage := range istorages {
if istorage.GetStorageType() == api.STORAGE_OPENSTACK_NOVA {
if utils.IsInStringArray(istorage.GetStorageType(), storageTypes) {
result = append(result, istorage)
continue
}
if storage := istorage.(*SStorage); len(storage.ExtraSpecs.VolumeBackendName) > 0 {
for _, pool := range schedulerPools {
if strings.HasPrefix(pool.Name, fmt.Sprintf("%s@%s", host.GetName(), storage.ExtraSpecs.VolumeBackendName)) {
result = append(result, istorage)
break
}
}
}
}
return result, nil
@@ -213,12 +200,12 @@ func (host *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudpr
BlockDeviceMappingV2 := []map[string]interface{}{}
if desc.SysDisk.StorageType != api.STORAGE_OPENSTACK_NOVA { //新建volume
storage, err := host.zone.getStorageByCategory(desc.SysDisk.StorageType)
istorage, err := host.zone.GetIStorageById(desc.SysDisk.StorageExternalId)
if err != nil {
return nil, err
return nil, errors.Wrapf(err, "GetIStorageById(%s)", desc.SysDisk.StorageExternalId)
}
_sysDisk, err := host.zone.region.CreateDisk(desc.ExternalImageId, storage.Name, "", desc.SysDisk.SizeGB, desc.SysDisk.Name)
_sysDisk, err := host.zone.region.CreateDisk(desc.ExternalImageId, istorage.GetName(), "", desc.SysDisk.SizeGB, desc.SysDisk.Name)
if err != nil {
return nil, err
}
@@ -234,11 +221,11 @@ func (host *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudpr
var _disk *SDisk
for _, disk := range desc.DataDisks {
storage, err := host.zone.getStorageByCategory(disk.StorageType)
istorage, err := host.zone.GetIStorageById(disk.StorageExternalId)
if err != nil {
break
}
_disk, err = host.zone.region.CreateDisk("", storage.Name, "", disk.SizeGB, disk.Name)
_disk, err = host.zone.region.CreateDisk("", istorage.GetName(), "", disk.SizeGB, disk.Name)
if err != nil {
break
}
+19
View File
@@ -38,4 +38,23 @@ func init() {
printList(storages, 0, 0, 0, []string{})
return nil
})
type CinderServiceListOptions struct {
REGION string `help:"Region Name"`
ZONE string `help:"Zone Name"`
}
shellutils.R(&CinderServiceListOptions{}, "cinder-service-list", "List cinder services", func(cli *openstack.SRegion, args *CinderServiceListOptions) error {
izone, err := cli.GetIZoneById(fmt.Sprintf("%s/%s/%s", openstack.CLOUD_PROVIDER_OPENSTACK, args.REGION, args.ZONE))
if err != nil {
return err
}
zone := izone.(*openstack.SZone)
services, err := zone.GetCinderServices()
if err != nil {
return err
}
printList(services, 0, 0, 0, []string{})
return nil
})
}
+13 -2
View File
@@ -20,11 +20,16 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/utils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
const (
DEFAULT_STORAGE_TYPE = "scheduler"
)
type SExtraSpecs struct {
VolumeBackendName string
}
@@ -74,7 +79,10 @@ func (storage *SStorage) GetIDisks() ([]cloudprovider.ICloudDisk, error) {
}
func (storage *SStorage) GetStorageType() string {
return strings.ToLower(storage.Name)
if len(storage.ExtraSpecs.VolumeBackendName) == 0 {
storage.ExtraSpecs.VolumeBackendName = DEFAULT_STORAGE_TYPE
}
return storage.ExtraSpecs.VolumeBackendName
}
func (storage *SStorage) GetMediumType() string {
@@ -94,7 +102,10 @@ func (storage *SStorage) GetStorageConf() jsonutils.JSONObject {
}
func (storage *SStorage) GetStatus() string {
return api.STORAGE_ONLINE
if utils.IsInStringArray(storage.GetStorageType(), storage.zone.getAvailableStorages()) {
return api.STORAGE_ONLINE
}
return api.STORAGE_OFFLINE
}
func (storage *SStorage) Refresh() error {
+71 -1
View File
@@ -59,7 +59,9 @@ type SZone struct {
cachedHosts map[string][]string
schedulerPools []SPool
schedulerPools []SPool
availableStorages []string
unavailableStorages []string
Hosts map[string]map[string]HostState
}
@@ -175,6 +177,74 @@ func (zone *SZone) fetchStorages() error {
return fmt.Errorf("failed to find storage types by cinder service")
}
type SCinderService struct {
ActiveBackendId string
// cinder-volume
Binary string
DisabledReason string
Frozen string
Host string
ReplicationStatus string
State string
Status string
UpdatedAt time.Time
Zone string
}
func (zone *SZone) GetCinderServices() ([]SCinderService, error) {
_, resp, err := zone.region.CinderList("/os-services", "", nil)
if err != nil {
return nil, errors.Wrap(err, "CinderList")
}
services := []SCinderService{}
err = resp.Unmarshal(&services, "services")
if err != nil {
return nil, errors.Wrap(err, "resp.Unmarshal")
}
return services, nil
}
func (zone *SZone) fetchCinderSerivces() error {
services, err := zone.GetCinderServices()
if err != nil {
return errors.Wrap(err, "GetCinderServices")
}
zone.availableStorages = []string{DEFAULT_STORAGE_TYPE, api.STORAGE_OPENSTACK_NOVA}
zone.unavailableStorages = []string{}
for _, service := range services {
if service.Binary == "cinder-volume" && strings.Contains(service.Host, "@") {
hostInfo := strings.Split(service.Host, "@")
storage := hostInfo[len(hostInfo)-1]
if service.State == "up" && service.Status == "enabled" {
zone.availableStorages = append(zone.availableStorages, storage)
continue
}
zone.unavailableStorages = append(zone.unavailableStorages, storage)
}
}
return nil
}
func (zone *SZone) getAvailableStorages() []string {
if zone.availableStorages == nil {
err := zone.fetchCinderSerivces()
if err != nil {
log.Errorf("fetchCinderSerivces error: %v", err)
}
}
return zone.availableStorages
}
func (zone *SZone) getUnavailableStorage() []string {
if zone.unavailableStorages == nil {
err := zone.fetchCinderSerivces()
if err != nil {
log.Errorf("fetchCinderSerivces error: %v", err)
}
}
return zone.unavailableStorages
}
func (zone *SZone) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
if zone.istorages == nil {
zone.fetchStorages()