mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 10:46:58 +08:00
Merge pull request #6103 from ioito/bugfix/qx-openstack-storage-sync
fix: 修复openstack存储同步问题
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user