Merge pull request #11052 from ioito/hotfix/qx-guest-list-optimized

fix(region): optimzed guest disks
This commit is contained in:
Zexi Li
2021-05-17 10:09:52 +08:00
committed by GitHub
4 changed files with 78 additions and 97 deletions
+14
View File
@@ -15,6 +15,7 @@
package compute
import (
"fmt"
"time"
"yunion.io/x/onecloud/pkg/apis"
@@ -270,6 +271,19 @@ type GuestDiskInfo struct {
Image string `json:"image,omitemtpy"`
}
func (self GuestDiskInfo) ShortDesc() string {
fs := ""
if len(self.ImageId) > 0 {
fs = "root"
} else if len(self.FsFormat) > 0 {
fs = self.FsFormat
} else {
fs = "none"
}
return fmt.Sprintf("disk%d:%dM/%s/%s/%s/%s/%s", self.Index, self.SizeMb,
self.DiskFormat, self.Driver, self.CacheMode, self.AioMode, fs)
}
type GuestJointResourceDetails struct {
apis.VirtualJointResourceBaseDetails
+64 -18
View File
@@ -57,13 +57,17 @@ func (manager *SGuestManager) FetchCustomizeColumns(
}
if len(fields) == 0 || fields.Contains("disk") {
gds := fetchGuestDiskSizes(guestIds)
gds := fetchGuestDisksInfo(guestIds)
if gds != nil {
for i := range rows {
if gd, ok := gds[guestIds[i]]; ok {
rows[i].DiskSizeMb = gd.DiskSizeMb
rows[i].DiskCount = gd.DiskCount
rows[i].DisksInfo, _ = gds[guestIds[i]]
rows[i].DiskCount = len(rows[i].DisksInfo)
shortDescs := []string{}
for _, info := range rows[i].DisksInfo {
rows[i].DiskSizeMb += int64(info.SizeMb)
shortDescs = append(shortDescs, info.ShortDesc())
}
rows[i].Disks = strings.Join(shortDescs, "\n")
}
}
}
@@ -214,25 +218,63 @@ type sGustDiskSize struct {
DiskCount int
}
func fetchGuestDiskSizes(guestIds []string) map[string]sGustDiskSize {
type sGuestDiskInfo struct {
api.GuestDiskInfo
GuestId string
}
func fetchGuestDisksInfo(guestIds []string) map[string][]api.GuestDiskInfo {
disks := DiskManager.Query().SubQuery()
guestdisks := GuestdiskManager.Query().SubQuery()
q := disks.Query(guestdisks.Field("guest_id"), sqlchemy.SUM("disk_size_mb", disks.Field("disk_size")), sqlchemy.COUNT("disk_count"))
storages := StorageManager.Query().SubQuery()
q := disks.Query(
disks.Field("id"),
disks.Field("name"),
disks.Field("fs_format"),
guestdisks.Field("index"),
disks.Field("disk_size").Label("size"),
disks.Field("disk_format"),
guestdisks.Field("driver"),
guestdisks.Field("cache_mode"),
guestdisks.Field("aio_mode"),
storages.Field("medium_type"),
storages.Field("storage_type"),
guestdisks.Field("iops"),
guestdisks.Field("bps"),
disks.Field("template_id").Label("image_id"),
guestdisks.Field("guest_id"),
)
q = q.Join(guestdisks, sqlchemy.Equals(guestdisks.Field("disk_id"), disks.Field("id")))
q = q.Join(storages, sqlchemy.Equals(disks.Field("storage_id"), storages.Field("id")))
q = q.Filter(sqlchemy.In(guestdisks.Field("guest_id"), guestIds))
q = q.GroupBy(guestdisks.Field("guest_id"))
gds := make([]sGustDiskSize, 0)
gds := []sGuestDiskInfo{}
err := q.All(&gds)
if err != nil && err != sql.ErrNoRows {
log.Errorf("query sGustDiskSize fail: %v", err)
if err != nil {
return nil
}
ret := make(map[string]sGustDiskSize)
imageIds := []string{}
ret := map[string][]api.GuestDiskInfo{}
for i := range gds {
ret[gds[i].GuestId] = gds[i]
if len(gds[i].ImageId) > 0 {
imageIds = append(imageIds, gds[i].ImageId)
}
_, ok := ret[gds[i].GuestId]
if !ok {
ret[gds[i].GuestId] = []api.GuestDiskInfo{}
}
ret[gds[i].GuestId] = append(ret[gds[i].GuestId], gds[i].GuestDiskInfo)
}
imageNames, err := db.FetchIdNameMap2(CachedimageManager, imageIds)
if err != nil {
return ret
}
for guestId, infos := range ret {
for i := range infos {
if len(infos[i].ImageId) > 0 {
ret[guestId][i].Image, _ = imageNames[infos[i].ImageId]
}
}
}
return ret
}
@@ -242,15 +284,19 @@ func (guest *SGuest) GetDisksSize() int {
}
func (guest *SGuest) getDiskSize() int {
result := fetchGuestDiskSizes([]string{guest.Id})
result := fetchGuestDisksInfo([]string{guest.Id})
if result == nil {
return -1
}
if gs, ok := result[guest.Id]; ok {
return int(gs.DiskSizeMb)
} else {
gds, ok := result[guest.Id]
if !ok {
return -1
}
size := 0
for _, gd := range gds {
size += gd.SizeMb
}
return size
}
func fetchGuestIPs(guestIds []string, virtual tristate.TriState) map[string][]string {
-57
View File
@@ -16,7 +16,6 @@ package models
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
@@ -249,62 +248,6 @@ func (self *SGuestdisk) GetJsonDescAtHost(host *SHost) jsonutils.JSONObject {
return desc
}
func (self *SGuestdisk) GetDetailedInfo() api.GuestDiskInfo {
desc := api.GuestDiskInfo{}
disk := self.GetDisk()
if disk == nil {
return desc
}
desc.Id = disk.Id
desc.Name = disk.Name
desc.FsFormat = disk.FsFormat
desc.DiskType = disk.DiskType
desc.Index = self.Index
desc.SizeMb = disk.DiskSize
desc.DiskFormat = disk.DiskFormat
desc.Driver = self.Driver
desc.CacheMode = self.CacheMode
desc.AioMode = self.AioMode
desc.Iops = self.Iops
desc.Bps = self.Bps
imageId := disk.GetTemplateId()
if len(imageId) > 0 {
desc.ImageId = imageId
cachedImageObj, _ := CachedimageManager.FetchById(imageId)
if cachedImageObj != nil {
cachedImage := cachedImageObj.(*SCachedimage)
desc.Image = cachedImage.GetName()
}
}
storage := disk.GetStorage()
if storage == nil {
return desc
}
desc.MediumType = storage.MediumType
desc.StorageType = storage.StorageType
return desc
}
func (self *SGuestdisk) GetDetailedString() string {
disk := self.GetDisk()
if disk == nil {
return ""
}
var fs string
if len(disk.GetTemplateId()) > 0 {
fs = "root"
} else if len(disk.GetFsFormat()) > 0 {
fs = disk.GetFsFormat()
} else {
fs = "none"
}
return fmt.Sprintf("disk%d:%dM/%s/%s/%s/%s/%s", self.Index, disk.DiskSize,
disk.DiskFormat, self.Driver, self.CacheMode, self.AioMode, fs)
}
func (self *SGuestdisk) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return db.DeleteModel(ctx, userCred, self)
}
-22
View File
@@ -1950,8 +1950,6 @@ func (self *SGuest) moreExtraInfo(
}
} else {
out.Networks = self.getNetworksDetails()
out.Disks = self.getDisksDetails()
out.DisksInfo = self.getDisksInfoDetails()
out.VirtualIps = strings.Join(self.getVirtualIPs(), ",")
out.SecurityRules = self.getSecurityGroupsRules()
@@ -2108,26 +2106,6 @@ func (self *SGuest) getNetworksDetails() string {
return buf.String()
}
func (self *SGuest) getDisksDetails() string {
var buf bytes.Buffer
for _, disk := range self.GetDisks() {
if details := disk.GetDetailedString(); len(details) > 0 {
buf.WriteString(details)
buf.WriteString("\n")
}
}
return buf.String()
}
func (self *SGuest) getDisksInfoDetails() []api.GuestDiskInfo {
disks := self.GetDisks()
details := make([]api.GuestDiskInfo, len(disks))
for i := range details {
details[i] = disks[i].GetDetailedInfo()
}
return details
}
func (self *SGuest) GetCdrom() *SGuestcdrom {
return self.getCdrom(false)
}