mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 10:46:58 +08:00
Merge pull request #1228 from ioito/hotfix/qx-zstack-optimized
fix zstack cdrom error
This commit is contained in:
@@ -215,6 +215,7 @@ type ICloudVM interface {
|
||||
|
||||
GetCreateTime() time.Time
|
||||
GetIHost() ICloudHost
|
||||
GetIHostId() string
|
||||
|
||||
GetIDisks() ([]ICloudDisk, error)
|
||||
GetINics() ([]ICloudNic, error)
|
||||
@@ -331,6 +332,7 @@ type ICloudDisk interface {
|
||||
IVirtualResource
|
||||
|
||||
GetIStorage() (ICloudStorage, error)
|
||||
GetIStorageId() string
|
||||
|
||||
// GetStatus() string
|
||||
GetDiskFormat() string
|
||||
|
||||
@@ -317,6 +317,15 @@ func (self *SManagedVirtualizedGuestDriver) RemoteDeployGuestForCreate(ctx conte
|
||||
}
|
||||
db.SetExternalId(guest, userCred, iVM.GetGlobalId())
|
||||
|
||||
if hostId := iVM.GetIHostId(); len(hostId) > 0 {
|
||||
host, err := db.FetchByExternalId(models.HostManager, hostId)
|
||||
if err != nil {
|
||||
log.Warningf("failed to found new hostId(%s) for ivm %s(%s) error: %v", hostId, guest.Name, guest.Id, err)
|
||||
} else if host.GetId() != guest.HostId {
|
||||
guest.OnScheduleToHost(ctx, userCred, host.GetId())
|
||||
}
|
||||
}
|
||||
|
||||
return iVM, nil
|
||||
}()
|
||||
|
||||
@@ -705,6 +714,15 @@ func (self *SManagedVirtualizedGuestDriver) OnGuestDeployTaskDataReceived(ctx co
|
||||
disk.ExpiredAt = diskInfo[i].ExpiredAt
|
||||
}
|
||||
|
||||
if len(diskInfo[i].StorageExternalId) > 0 {
|
||||
storage, err := db.FetchByExternalId(models.StorageManager, diskInfo[i].StorageExternalId)
|
||||
if err != nil {
|
||||
log.Warningf("failed to found storage by externalId %s error: %v", diskInfo[i].StorageExternalId, err)
|
||||
} else if disk.StorageId != storage.GetId() {
|
||||
disk.StorageId = storage.GetId()
|
||||
}
|
||||
}
|
||||
|
||||
if len(diskInfo[i].Metadata) > 0 {
|
||||
for key, value := range diskInfo[i].Metadata {
|
||||
if err := disk.SetMetadata(ctx, key, value, task.GetUserCred()); err != nil {
|
||||
|
||||
@@ -26,18 +26,19 @@ import (
|
||||
)
|
||||
|
||||
type SDiskInfo struct {
|
||||
DiskType string
|
||||
Size int
|
||||
Uuid string
|
||||
BillingType string
|
||||
FsFromat string
|
||||
AutoDelete bool
|
||||
TemplateId string
|
||||
DiskFormat string
|
||||
Path string
|
||||
Driver string
|
||||
CacheMode string
|
||||
ExpiredAt time.Time
|
||||
DiskType string
|
||||
Size int
|
||||
Uuid string
|
||||
BillingType string
|
||||
FsFromat string
|
||||
AutoDelete bool
|
||||
TemplateId string
|
||||
DiskFormat string
|
||||
Path string
|
||||
Driver string
|
||||
CacheMode string
|
||||
ExpiredAt time.Time
|
||||
StorageExternalId string
|
||||
|
||||
Metadata map[string]string
|
||||
}
|
||||
@@ -86,6 +87,7 @@ func fetchIVMinfo(desc cloudprovider.SManagedVMCreateConfig, iVM cloudprovider.I
|
||||
dinfo.TemplateId = idisks[i].GetTemplateId()
|
||||
dinfo.FsFromat = idisks[i].GetFsFormat()
|
||||
dinfo.ExpiredAt = idisks[i].GetExpiredAt()
|
||||
dinfo.StorageExternalId = idisks[i].GetIStorageId()
|
||||
if metaData := idisks[i].GetMetadata(); metaData != nil {
|
||||
dinfo.Metadata = make(map[string]string, 0)
|
||||
metadata := map[string]string{}
|
||||
|
||||
@@ -1946,14 +1946,14 @@ func (self *SGuest) PerformChangeConfig(ctx context.Context, userCred mcclient.T
|
||||
}
|
||||
|
||||
provider, e := self.GetHost().GetProviderFactory()
|
||||
if e != nil || provider.IsOnPremise() {
|
||||
if e != nil || !provider.IsPublicCloud() {
|
||||
for storageId, needSize := range diskSizes {
|
||||
iStorage, err := StorageManager.FetchById(storageId)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewBadRequestError("Fetch storage error: %s", err)
|
||||
}
|
||||
storage := iStorage.(*SStorage)
|
||||
if storage.GetFreeCapacity() < int64(needSize) {
|
||||
if storage.GetFreeCapacity() > 0 && storage.GetFreeCapacity() < int64(needSize) {
|
||||
return nil, httperrors.NewInsufficientResourceError("Not enough free space")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,3 +19,7 @@ type SDisk struct{}
|
||||
func (self *SDisk) GetExtSnapshotPolicyId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SDisk) GetIStorageId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// 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 multicloud
|
||||
|
||||
type SInstanceBase struct {
|
||||
SResourceBase
|
||||
}
|
||||
|
||||
func (instance *SInstanceBase) GetIHostId() string {
|
||||
return ""
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import (
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud"
|
||||
"yunion.io/x/onecloud/pkg/util/billing"
|
||||
)
|
||||
|
||||
@@ -80,6 +81,8 @@ type SVpcAttributes struct {
|
||||
}
|
||||
|
||||
type SInstance struct {
|
||||
multicloud.SInstanceBase
|
||||
|
||||
host *SHost
|
||||
|
||||
// idisks []cloudprovider.ICloudDisk
|
||||
|
||||
@@ -21,6 +21,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/multicloud"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
@@ -70,6 +72,8 @@ type SVpcAttributes struct {
|
||||
}
|
||||
|
||||
type SInstance struct {
|
||||
multicloud.SInstanceBase
|
||||
|
||||
host *SHost
|
||||
RegionId string
|
||||
ZoneId string
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
billing_api "yunion.io/x/onecloud/pkg/apis/billing"
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud"
|
||||
"yunion.io/x/onecloud/pkg/util/billing"
|
||||
)
|
||||
|
||||
@@ -131,6 +132,8 @@ type ClassicVirtualMachineProperties struct {
|
||||
}
|
||||
|
||||
type SClassicInstance struct {
|
||||
multicloud.SInstanceBase
|
||||
|
||||
host *SClassicHost
|
||||
|
||||
idisks []cloudprovider.ICloudDisk
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
billing_api "yunion.io/x/onecloud/pkg/apis/billing"
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud"
|
||||
"yunion.io/x/onecloud/pkg/util/billing"
|
||||
)
|
||||
|
||||
@@ -177,6 +178,7 @@ type VirtualMachineProperties struct {
|
||||
}
|
||||
|
||||
type SInstance struct {
|
||||
multicloud.SInstanceBase
|
||||
host *SHost
|
||||
|
||||
Properties VirtualMachineProperties
|
||||
|
||||
@@ -176,6 +176,10 @@ func (self *SVirtualMachine) GetIHost() cloudprovider.ICloudHost {
|
||||
return self.ihost
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) GetIHostId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SVirtualMachine) getIHost() cloudprovider.ICloudHost {
|
||||
vm := self.getVmObj()
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import (
|
||||
billing_api "yunion.io/x/onecloud/pkg/apis/billing"
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud"
|
||||
"yunion.io/x/onecloud/pkg/util/billing"
|
||||
"yunion.io/x/onecloud/pkg/util/huawei/client/modules"
|
||||
)
|
||||
@@ -95,6 +96,8 @@ type SysTag struct {
|
||||
// https://support.huaweicloud.com/api-ecs/zh-cn_topic_0094148849.html
|
||||
// https://support.huaweicloud.com/api-bpconsole/zh-cn_topic_0100166287.html v1.1 支持创建包年/包月的弹性云服务器
|
||||
type SInstance struct {
|
||||
multicloud.SInstanceBase
|
||||
|
||||
host *SHost
|
||||
|
||||
ID string `json:"id"`
|
||||
|
||||
@@ -20,6 +20,8 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/multicloud"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/utils"
|
||||
@@ -92,6 +94,8 @@ type SFault struct {
|
||||
}
|
||||
|
||||
type SInstance struct {
|
||||
multicloud.SInstanceBase
|
||||
|
||||
host *SHost
|
||||
|
||||
DiskConfig string `json:"OS-DCF:diskConfig,omitempty"`
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
billing_api "yunion.io/x/onecloud/pkg/apis/billing"
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud"
|
||||
"yunion.io/x/onecloud/pkg/util/billing"
|
||||
)
|
||||
|
||||
@@ -92,6 +93,8 @@ type Tag struct {
|
||||
}
|
||||
|
||||
type SInstance struct {
|
||||
multicloud.SInstanceBase
|
||||
|
||||
host *SHost
|
||||
|
||||
image *SImage
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
@@ -34,6 +35,8 @@ import (
|
||||
)
|
||||
|
||||
type SInstance struct {
|
||||
multicloud.SInstanceBase
|
||||
|
||||
host *SHost
|
||||
|
||||
UHostID string `json:"UHostId"`
|
||||
|
||||
@@ -169,6 +169,21 @@ func (disk *SDisk) GetIStorage() (cloudprovider.ICloudStorage, error) {
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (disk *SDisk) GetIStorageId() string {
|
||||
storage, err := disk.region.GetStorage(disk.PrimaryStorageUUID)
|
||||
if err != nil {
|
||||
return disk.PrimaryStorageUUID
|
||||
} else if storage.Type == StorageTypeLocal && len(disk.VMInstanceUUID) > 0 {
|
||||
instnace, err := disk.region.GetInstance(disk.VMInstanceUUID)
|
||||
if err != nil {
|
||||
log.Warningf("failed to get instance %s for disk %s(%s) error: %v", disk.VMInstanceUUID, disk.Name, disk.UUID, err)
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("%s/%s", disk.PrimaryStorageUUID, instnace.LastHostUUID)
|
||||
}
|
||||
return disk.PrimaryStorageUUID
|
||||
}
|
||||
|
||||
func (disk *SDisk) GetStatus() string {
|
||||
switch disk.Status {
|
||||
case "Ready":
|
||||
|
||||
+64
-34
@@ -250,8 +250,25 @@ func (region *SRegion) cleanDisks(diskIds []string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (region *SRegion) createDataDisks(disks []cloudprovider.SDiskInfo) ([]string, error) {
|
||||
func (region *SRegion) createDataDisks(disks []cloudprovider.SDiskInfo, hostId string) ([]string, error) {
|
||||
diskIds := []string{}
|
||||
|
||||
storages, err := region.GetStorages("", "", "")
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "createDataDisks.GetStorages")
|
||||
}
|
||||
|
||||
localstorages := []SLocalStorage{}
|
||||
|
||||
for _, storage := range storages {
|
||||
if storage.Type == StorageTypeLocal {
|
||||
localstorage, _ := region.GetLocalStorage(storage.UUID, hostId)
|
||||
if localstorage != nil {
|
||||
localstorages = append(localstorages, *localstorage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < len(disks); i++ {
|
||||
storageInfo := strings.Split(disks[i].StorageExternalId, "/")
|
||||
if len(storageInfo) == 0 {
|
||||
@@ -262,9 +279,9 @@ func (region *SRegion) createDataDisks(disks []cloudprovider.SDiskInfo) ([]strin
|
||||
return diskIds, errors.Wrapf(err, "createDataDisks")
|
||||
}
|
||||
|
||||
hostId, poolName := "", ""
|
||||
switch storage.Type {
|
||||
case StorageTypeCeph:
|
||||
poolName := ""
|
||||
for _, pool := range storage.Pools {
|
||||
if pool.Type == CephPoolTypeData {
|
||||
poolName = pool.PoolName
|
||||
@@ -273,36 +290,49 @@ func (region *SRegion) createDataDisks(disks []cloudprovider.SDiskInfo) ([]strin
|
||||
if len(poolName) == 0 {
|
||||
return diskIds, fmt.Errorf("failed to found ceph data pool for storage %s to createDataDisk", storage.Name)
|
||||
}
|
||||
disk, err := region.CreateDisk(disks[i].Name, storage.UUID, "", poolName, disks[i].SizeGB, "")
|
||||
if err != nil {
|
||||
return diskIds, err
|
||||
}
|
||||
diskIds = append(diskIds, disk.UUID)
|
||||
case StorageTypeLocal:
|
||||
hostId = storageInfo[1]
|
||||
if len(localstorages) == 0 {
|
||||
return nil, fmt.Errorf("No validate localstorage")
|
||||
}
|
||||
var disk *SDisk
|
||||
var err error
|
||||
for _, localstorage := range localstorages {
|
||||
disk, err = region.CreateDisk(disks[i].Name, localstorage.primaryStorageID, hostId, "", disks[i].SizeGB, "")
|
||||
if err != nil {
|
||||
log.Warningf("createDataDisks error: %v", err)
|
||||
} else {
|
||||
diskIds = append(diskIds, disk.UUID)
|
||||
break
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return diskIds, err
|
||||
}
|
||||
default:
|
||||
return diskIds, fmt.Errorf("not support storageType %s", disks[i].StorageType)
|
||||
}
|
||||
|
||||
disk, err := region.CreateDisk(disks[i].Name, storage.UUID, hostId, poolName, disks[i].SizeGB, "")
|
||||
if err != nil {
|
||||
return diskIds, err
|
||||
}
|
||||
diskIds = append(diskIds, disk.UUID)
|
||||
}
|
||||
return diskIds, nil
|
||||
}
|
||||
|
||||
func (host *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) {
|
||||
diskIds, err := host.zone.region.createDataDisks(desc.DataDisks)
|
||||
instance, err := host.zone.region._createVM(desc, host.ZoneUUID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "host.zone.region._createVM")
|
||||
}
|
||||
|
||||
diskIds, err := host.zone.region.createDataDisks(desc.DataDisks, instance.HostUUID)
|
||||
if err != nil {
|
||||
defer host.zone.region.cleanDisks(diskIds)
|
||||
return nil, err
|
||||
}
|
||||
if len(desc.SysDisk.StorageExternalId) == 0 {
|
||||
return nil, fmt.Errorf("invalidate root disk storage externalId")
|
||||
}
|
||||
rootStorageId := strings.Split(desc.SysDisk.StorageExternalId, "/")[0]
|
||||
instance, err := host.zone.region._createVM(desc, host.UUID, rootStorageId)
|
||||
if err != nil {
|
||||
defer host.zone.region.cleanDisks(diskIds)
|
||||
return nil, err
|
||||
defer host.zone.region.DeleteVM(instance.UUID)
|
||||
return nil, errors.Wrapf(err, "host.zone.region.createDataDisks")
|
||||
}
|
||||
|
||||
for i := 0; i < len(diskIds); i++ {
|
||||
err = host.zone.region.AttachDisk(instance.UUID, diskIds[i])
|
||||
if err != nil {
|
||||
@@ -316,7 +346,7 @@ func (host *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudpr
|
||||
return host.GetIVMById(instance.UUID)
|
||||
}
|
||||
|
||||
func (region *SRegion) _createVM(desc *cloudprovider.SManagedVMCreateConfig, hostId string, rootStorageId string) (*SInstance, error) {
|
||||
func (region *SRegion) _createVM(desc *cloudprovider.SManagedVMCreateConfig, zoneId string) (*SInstance, error) {
|
||||
l3Id := strings.Split(desc.ExternalNetworkId, "/")[0]
|
||||
if len(l3Id) == 0 {
|
||||
return nil, fmt.Errorf("invalid networkid: %s", desc.ExternalNetworkId)
|
||||
@@ -345,13 +375,13 @@ func (region *SRegion) _createVM(desc *cloudprovider.SManagedVMCreateConfig, hos
|
||||
return nil, fmt.Errorf("instance type %dC%dMB not avaiable", desc.Cpu, desc.MemoryMB)
|
||||
}
|
||||
}
|
||||
return region.CreateInstance(desc, l3Id, hostId, rootStorageId, offerings)
|
||||
return region.CreateInstance(desc, l3Id, zoneId, offerings)
|
||||
}
|
||||
|
||||
func (region *SRegion) CreateInstance(desc *cloudprovider.SManagedVMCreateConfig, l3Id, hostId, rootStorageId string, offerings map[string]string) (*SInstance, error) {
|
||||
func (region *SRegion) CreateInstance(desc *cloudprovider.SManagedVMCreateConfig, l3Id, zoneId string, offerings map[string]string) (*SInstance, error) {
|
||||
instance := &SInstance{}
|
||||
systemTags := []string{
|
||||
"cdroms::Empty::None::None",
|
||||
"createWithoutCdRom::true",
|
||||
"usbRedirect::false",
|
||||
fmt.Sprintf("staticIp::%s::%s", l3Id, desc.IpAddr),
|
||||
"vmConsoleMode::vnc",
|
||||
@@ -374,18 +404,18 @@ func (region *SRegion) CreateInstance(desc *cloudprovider.SManagedVMCreateConfig
|
||||
"l3NetworkUuids": []string{
|
||||
l3Id,
|
||||
},
|
||||
"hostUuid": hostId,
|
||||
"dataVolumeSystemTags": []string{},
|
||||
"rootVolumeSystemTags": []string{},
|
||||
"vmMachineType": "",
|
||||
"tagUuids": []string{},
|
||||
"defaultL3NetworkUuid": l3Id,
|
||||
"primaryStorageUuidForRootVolume": rootStorageId,
|
||||
"dataDiskOfferingUuids": []string{},
|
||||
"systemTags": systemTags,
|
||||
"vmNicConfig": []string{},
|
||||
"zoneUuid": zoneId,
|
||||
"dataVolumeSystemTags": []string{},
|
||||
"rootVolumeSystemTags": []string{},
|
||||
"vmMachineType": "",
|
||||
"tagUuids": []string{},
|
||||
"defaultL3NetworkUuid": l3Id,
|
||||
"dataDiskOfferingUuids": []string{},
|
||||
"systemTags": systemTags,
|
||||
"vmNicConfig": []string{},
|
||||
},
|
||||
}
|
||||
|
||||
log.Debugf("Try instanceOffering : %s", offerName)
|
||||
err = region.client.create("vm-instances", jsonutils.Marshal(params), instance)
|
||||
if err == nil {
|
||||
|
||||
@@ -49,7 +49,7 @@ func (v ImageServers) Less(i, j int) bool {
|
||||
|
||||
func (region *SRegion) GetImageServers(zoneId string) ([]SImageServer, error) {
|
||||
servers := []SImageServer{}
|
||||
params := []string{"q=state=Enabled", "q=status=Connected", "q=type=ImageStoreBackupStorage"}
|
||||
params := []string{"q=state=Enabled", "q=status=Connected"}
|
||||
if SkipEsxi {
|
||||
params = append(params, "q=type!=VCenter")
|
||||
}
|
||||
|
||||
@@ -108,6 +108,13 @@ func (instance *SInstance) GetIHost() cloudprovider.ICloudHost {
|
||||
return instance.host
|
||||
}
|
||||
|
||||
func (instance *SInstance) GetIHostId() string {
|
||||
if len(instance.LastHostUUID) > 0 {
|
||||
return instance.LastHostUUID
|
||||
}
|
||||
return instance.HostUUID
|
||||
}
|
||||
|
||||
func (instance *SInstance) GetId() string {
|
||||
return instance.UUID
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user