Merge pull request #1228 from ioito/hotfix/qx-zstack-optimized

fix zstack cdrom error
This commit is contained in:
yunion-ci-robot
2019-06-16 17:30:51 +08:00
committed by GitHub
19 changed files with 179 additions and 49 deletions
+2
View File
@@ -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 {
+14 -12
View File
@@ -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{}
+2 -2
View File
@@ -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")
}
}
+4
View File
@@ -19,3 +19,7 @@ type SDisk struct{}
func (self *SDisk) GetExtSnapshotPolicyId() string {
return ""
}
func (self *SDisk) GetIStorageId() string {
return ""
}
+23
View File
@@ -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 ""
}
+3
View File
@@ -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
+4
View File
@@ -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
+3
View File
@@ -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
+2
View File
@@ -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
+4
View File
@@ -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()
+3
View File
@@ -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"`
+4
View File
@@ -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"`
+3
View File
@@ -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
+3
View File
@@ -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"`
+15
View File
@@ -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
View File
@@ -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 {
+1 -1
View File
@@ -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")
}
+7
View File
@@ -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
}