fix(region): cpu socket (#18731)

This commit is contained in:
屈轩
2023-11-21 14:58:27 +08:00
committed by GitHub
parent 1d9a291fe9
commit 2e1c5fa844
21 changed files with 121 additions and 52 deletions

2
go.mod
View File

@@ -86,7 +86,7 @@ require (
k8s.io/client-go v0.19.3
k8s.io/cluster-bootstrap v0.19.3
moul.io/http2curl/v2 v2.3.0
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20231117073513-e4f90b4cabe4
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20231120065010-32185e2427ba
yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32
yunion.io/x/jsonutils v1.0.1-0.20230613121553-0f3b41e2ef19
yunion.io/x/log v1.0.1-0.20230411060016-feb3f46ab361

4
go.sum
View File

@@ -1192,8 +1192,8 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20231117073513-e4f90b4cabe4 h1:cMkp0GGx770vEryaMBZLWdcR3lhmScM+FbE6XWmqEZU=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20231117073513-e4f90b4cabe4/go.mod h1:aj1gR9PPb6eqqKOwvANe26CoZFY8ydmXy0fuvgKYXH0=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20231120065010-32185e2427ba h1:+q78oFUtoFfoIwP6KRSBE3EGX4QRgZNjwIqNnfXCQs8=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20231120065010-32185e2427ba/go.mod h1:aj1gR9PPb6eqqKOwvANe26CoZFY8ydmXy0fuvgKYXH0=
yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32 h1:v7POYkQwo1XzOxBoIoRVr/k0V9Y5JyjpshlIFa9raug=
yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=

View File

@@ -429,6 +429,11 @@ type ServerCreateInput struct {
// default: 1
VcpuCount int `json:"vcpu_count"`
// cpu卡槽数
// 目前仅vmware支持此参数
// default: 1
CpuSockets int `json:"cpu_sockets"`
// 用户自定义启动脚本
// 支持 #cloud-config yaml 格式及shell脚本
// 支持特殊user data平台: Aliyun, Qcloud, Azure, Apsara, Ucloud

View File

@@ -764,6 +764,8 @@ type ServerChangeConfigInput struct {
// swagger: ignore
Flavor string `json:"flavor" yunion-deprecated-by:"instance_type"`
// cpu卡槽数
CpuSockets *int `json:"cpu_sockets"`
// cpu大小
VcpuCount int `json:"vcpu_count"`
// 内存大小, 1024M, 1G
@@ -809,6 +811,7 @@ type GuestJsonDesc struct {
Description string `json:"description"`
UUID string `json:"uuid"`
Mem int `json:"mem"`
CpuSockets int `json:"cpu_sockets"`
Cpu int `json:"cpu"`
Vga string `json:"vga"`
Vdi string `json:"vdi"`

View File

@@ -237,8 +237,8 @@ func (drv *SBaseGuestDriver) DoGuestCreateDisksTask(ctx context.Context, guest *
return fmt.Errorf("Not Implement")
}
func (drv *SBaseGuestDriver) RequestChangeVmConfig(ctx context.Context, guest *models.SGuest, task taskman.ITask, instanceType string, vcpuCount, vmemSize int64) error {
return fmt.Errorf("Not Implement")
func (drv *SBaseGuestDriver) RequestChangeVmConfig(ctx context.Context, guest *models.SGuest, task taskman.ITask, instanceType string, vcpuCount, cpuSockets, vmemSize int64) error {
return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestChangeVmConfig")
}
func (drv *SBaseGuestDriver) NeedRequestGuestHotAddIso(ctx context.Context, guest *models.SGuest) bool {

View File

@@ -196,7 +196,7 @@ func (self *SContainerDriver) DoGuestCreateDisksTask(ctx context.Context, guest
return self.newUnsupportOperationError("create disk")
}
func (self *SContainerDriver) RequestChangeVmConfig(ctx context.Context, guest *models.SGuest, task taskman.ITask, instanceType string, vcpuCount, vmemSize int64) error {
func (self *SContainerDriver) RequestChangeVmConfig(ctx context.Context, guest *models.SGuest, task taskman.ITask, instanceType string, vcpuCount, cpuSockets, vmemSize int64) error {
return self.newUnsupportOperationError("change config")
}

View File

@@ -274,6 +274,10 @@ func (self *SESXiGuestDriver) ValidateCreateData(ctx context.Context, userCred m
data.Disks[i].Format = "vmdk"
}
if data.CpuSockets > data.VcpuCount {
return nil, httperrors.NewInputParameterError("The number of cpu sockets cannot be greater than the number of cpus")
}
// check disk config
if len(data.Disks) == 0 {
return data, nil

View File

@@ -431,7 +431,7 @@ func (self *SKVMGuestDriver) NeedStopForChangeSpec(ctx context.Context, guest *m
// apis.IsARM(guest.OsArch)
}
func (self *SKVMGuestDriver) RequestChangeVmConfig(ctx context.Context, guest *models.SGuest, task taskman.ITask, instanceType string, vcpuCount, vmemSize int64) error {
func (self *SKVMGuestDriver) RequestChangeVmConfig(ctx context.Context, guest *models.SGuest, task taskman.ITask, instanceType string, vcpuCount, cpuSockets, vmemSize int64) error {
if jsonutils.QueryBoolean(task.GetParams(), "guest_online", false) {
addCpu := vcpuCount - int64(guest.VcpuCount)
addMem := vmemSize - int64(guest.VmemSize)

View File

@@ -989,8 +989,11 @@ func (drv *SManagedVirtualizedGuestDriver) DoGuestCreateDisksTask(ctx context.Co
return nil
}
func (drv *SManagedVirtualizedGuestDriver) RequestChangeVmConfig(ctx context.Context, guest *models.SGuest, task taskman.ITask, instanceType string, vcpuCount, vmemSize int64) error {
host, _ := guest.GetHost()
func (drv *SManagedVirtualizedGuestDriver) RequestChangeVmConfig(ctx context.Context, guest *models.SGuest, task taskman.ITask, instanceType string, vcpuCount, cpuSockets, vmemSize int64) error {
host, err := guest.GetHost()
if err != nil {
return errors.Wrapf(err, "GetHost")
}
ihost, err := host.GetIHost(ctx)
if err != nil {
return err
@@ -1002,22 +1005,21 @@ func (drv *SManagedVirtualizedGuestDriver) RequestChangeVmConfig(ctx context.Con
}
if len(instanceType) == 0 {
region, _ := host.GetRegion()
region, err := host.GetRegion()
if err != nil {
return err
}
sku, err := models.ServerSkuManager.GetMatchedSku(region.GetId(), vcpuCount, vmemSize)
if err != nil {
return errors.Wrap(err, "ManagedVirtualizedGuestDriver.RequestChangeVmConfig.GetMatchedSku")
return errors.Wrapf(err, "GetMatchedSku %s %dC%dM", region.GetId(), vcpuCount, vmemSize)
}
if sku == nil {
return errors.Wrap(errors.ErrNotFound, "ManagedVirtualizedGuestDriver.RequestChangeVmConfig.GetMatchedSku")
}
instanceType = sku.Name
}
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
config := &cloudprovider.SManagedVMChangeConfig{
Cpu: int(vcpuCount),
CpuSocket: int(cpuSockets),
MemoryMB: int(vmemSize),
InstanceType: instanceType,
}

View File

@@ -2697,13 +2697,14 @@ func (self *SGuest) PerformChangeConfig(ctx context.Context, userCred mcclient.T
}
var addCpu, addMem int
var cpuChanged, memChanged bool
var cpuChanged, cpuSocketsChanged, memChanged bool
confs := jsonutils.NewDict()
confs.Add(jsonutils.Marshal(map[string]interface{}{
"instance_type": self.InstanceType,
"vcpu_count": self.VcpuCount,
"vmem_size": self.VmemSize,
"cpu_sockets": self.CpuSockets,
}), "old")
if len(input.InstanceType) > 0 {
sku, err := ServerSkuManager.FetchSkuByNameAndProvider(input.InstanceType, self.GetDriver().GetProvider(), true)
@@ -2735,24 +2736,33 @@ func (self *SGuest) PerformChangeConfig(ctx context.Context, userCred mcclient.T
addCpu = input.VcpuCount - self.VcpuCount
confs.Add(jsonutils.NewInt(int64(input.VcpuCount)), "vcpu_count")
}
if !regutils.MatchSize(input.VmemSize) {
return nil, httperrors.NewBadRequestError("Memory size %q must be number[+unit], like 256M, 1G or 256", input.VmemSize)
}
nVmem, err := fileutils.GetSizeMb(input.VmemSize, 'M', 1024)
if err != nil {
httperrors.NewBadRequestError("Params vmem_size parse error")
}
if nVmem != self.VmemSize {
memChanged = true
addMem = nVmem - self.VmemSize
err = confs.Add(jsonutils.NewInt(int64(nVmem)), "vmem_size")
if len(input.VmemSize) > 0 {
if !regutils.MatchSize(input.VmemSize) {
return nil, httperrors.NewBadRequestError("Memory size %q must be number[+unit], like 256M, 1G or 256", input.VmemSize)
}
nVmem, err := fileutils.GetSizeMb(input.VmemSize, 'M', 1024)
if err != nil {
return nil, httperrors.NewBadRequestError("Params vmem_size parse error")
httperrors.NewBadRequestError("Params vmem_size parse error")
}
if nVmem != self.VmemSize {
memChanged = true
addMem = nVmem - self.VmemSize
err = confs.Add(jsonutils.NewInt(int64(nVmem)), "vmem_size")
if err != nil {
return nil, httperrors.NewBadRequestError("Params vmem_size parse error")
}
}
}
}
if input.CpuSockets != nil && *input.CpuSockets != self.CpuSockets {
if *input.CpuSockets > self.VcpuCount+addCpu {
return nil, httperrors.NewInputParameterError("The number of cpu sockets cannot be greater than the number of cpus")
}
cpuSocketsChanged = true
confs.Set("cpu_sockets", jsonutils.NewInt(int64(*input.CpuSockets)))
}
if self.Status == api.VM_RUNNING && (cpuChanged || memChanged) && self.GetDriver().NeedStopForChangeSpec(ctx, self, cpuChanged, memChanged) {
if self.Status == api.VM_RUNNING && (cpuChanged || memChanged || cpuSocketsChanged) && self.GetDriver().NeedStopForChangeSpec(ctx, self, cpuChanged, memChanged) {
return nil, httperrors.NewInvalidStatusError("cannot change CPU/Memory spec in status %s", self.Status)
}

View File

@@ -165,7 +165,7 @@ type IGuestDriver interface {
AllowReconfigGuest() bool
DoGuestCreateDisksTask(ctx context.Context, guest *SGuest, task taskman.ITask) error
RequestChangeVmConfig(ctx context.Context, guest *SGuest, task taskman.ITask, instanceType string, vcpuCount, vmemSize int64) error
RequestChangeVmConfig(ctx context.Context, guest *SGuest, task taskman.ITask, instanceType string, vcpuCount, cpuSockets, vmemSize int64) error
NeedRequestGuestHotAddIso(ctx context.Context, guest *SGuest) bool
RequestGuestHotAddIso(ctx context.Context, guest *SGuest, path string, boot bool, task taskman.ITask) error

View File

@@ -121,6 +121,8 @@ type SGuest struct {
db.SEncryptedResource
// CPU大小
CpuSockets int `nullable:"false" default:"1" list:"user" create:"optional"`
// CPU大小
VcpuCount int `nullable:"false" default:"1" list:"user" create:"optional"`
// 内存大小, 单位MB
@@ -3015,6 +3017,7 @@ func (g *SGuest) syncWithCloudVM(ctx context.Context, userCred mcclient.TokenCre
}
g.VcpuCount = extVM.GetVcpuCount()
g.CpuSockets = extVM.GetCpuSockets()
g.BootOrder = extVM.GetBootOrder()
g.Vga = extVM.GetVga()
g.Vdi = extVM.GetVdi()
@@ -3108,6 +3111,7 @@ func (manager *SGuestManager) newCloudVM(ctx context.Context, userCred mcclient.
guest.InferPowerStates()
guest.ExternalId = extVM.GetGlobalId()
guest.VcpuCount = extVM.GetVcpuCount()
guest.CpuSockets = extVM.GetCpuSockets()
guest.BootOrder = extVM.GetBootOrder()
guest.Vga = extVM.GetVga()
guest.Vdi = extVM.GetVdi()
@@ -4911,6 +4915,7 @@ func (self *SGuest) GetJsonDescAtHypervisor(ctx context.Context, host *SHost) *a
UUID: self.Id,
Mem: self.VmemSize,
Cpu: self.VcpuCount,
CpuSockets: self.CpuSockets,
Vga: self.getVga(),
Vdi: self.GetVdi(),
Machine: self.getMachine(),

View File

@@ -194,11 +194,12 @@ func (task *GuestChangeConfigTask) OnCreateDisksCompleteFailed(ctx context.Conte
func (task *GuestChangeConfigTask) OnCreateDisksComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
guest := obj.(*models.SGuest)
if task.Params.Contains("instance_type") || task.Params.Contains("vcpu_count") || task.Params.Contains("vmem_size") {
if task.Params.Contains("instance_type") || task.Params.Contains("vcpu_count") || task.Params.Contains("vmem_size") || task.Params.Contains("cpu_sockets") {
task.SetStage("OnGuestChangeCpuMemSpecComplete", nil)
instanceType, _ := task.Params.GetString("instance_type")
vcpuCount, _ := task.Params.Int("vcpu_count")
vmemSize, _ := task.Params.Int("vmem_size")
cpuSockets, _ := task.Params.Int("cpu_sockets")
if len(instanceType) > 0 {
provider := guest.GetDriver().GetProvider()
sku, err := models.ServerSkuManager.FetchSkuByNameAndProvider(instanceType, provider, false)
@@ -216,14 +217,14 @@ func (task *GuestChangeConfigTask) OnCreateDisksComplete(ctx context.Context, ob
vmemSize = int64(guest.VmemSize)
}
}
task.startGuestChangeCpuMemSpec(ctx, guest, instanceType, vcpuCount, vmemSize)
task.startGuestChangeCpuMemSpec(ctx, guest, instanceType, vcpuCount, cpuSockets, vmemSize)
} else {
task.OnGuestChangeCpuMemSpecComplete(ctx, obj, data)
}
}
func (task *GuestChangeConfigTask) startGuestChangeCpuMemSpec(ctx context.Context, guest *models.SGuest, instanceType string, vcpuCount int64, vmemSize int64) {
err := guest.GetDriver().RequestChangeVmConfig(ctx, guest, task, instanceType, vcpuCount, vmemSize)
func (task *GuestChangeConfigTask) startGuestChangeCpuMemSpec(ctx context.Context, guest *models.SGuest, instanceType string, vcpuCount, cpuSockets int64, vmemSize int64) {
err := guest.GetDriver().RequestChangeVmConfig(ctx, guest, task, instanceType, vcpuCount, cpuSockets, vmemSize)
if err != nil {
task.markStageFailed(ctx, guest, jsonutils.NewString(err.Error()))
return
@@ -235,6 +236,7 @@ func (task *GuestChangeConfigTask) OnGuestChangeCpuMemSpecComplete(ctx context.C
instanceType, _ := task.Params.GetString("instance_type")
vcpuCount, _ := task.Params.Int("vcpu_count")
cpuSockets, _ := task.Params.Int("cpu_sockets")
vmemSize, _ := task.Params.Int("vmem_size")
if len(instanceType) == 0 {
@@ -251,6 +253,9 @@ func (task *GuestChangeConfigTask) OnGuestChangeCpuMemSpecComplete(ctx context.C
if vcpuCount > 0 {
guest.VcpuCount = int(vcpuCount)
}
if cpuSockets > 0 {
guest.CpuSockets = int(cpuSockets)
}
if vmemSize > 0 {
guest.VmemSize = int(vmemSize)
}

View File

@@ -409,6 +409,7 @@ type ServerCreateOptionalOptions struct {
ServerConfigs
MemSpec string `help:"Memory size Or Instance Type" metavar:"MEMSPEC" json:"-"`
CpuSockets int `help:"Cpu sockets"`
EnableMemclean bool `help:"clean guest memory after guest exit" json:"enable_memclean"`
Keypair string `help:"SSH Keypair"`
@@ -996,9 +997,10 @@ func (o *ServerRebuildRootOptions) Description() string {
type ServerChangeConfigOptions struct {
ServerIdOptions
VcpuCount *int `help:"New number of Virtual CPU cores" json:"vcpu_count" token:"ncpu"`
VmemSize string `help:"New memory size" json:"vmem_size" token:"vmem"`
Disk []string `help:"Data disk description, from the 1st data disk to the last one, empty string if no change for this data disk"`
VcpuCount *int `help:"New number of Virtual CPU cores" json:"vcpu_count" token:"ncpu"`
CpuSockets *int `help:"Cpu sockets"`
VmemSize string `help:"New memory size" json:"vmem_size" token:"vmem"`
Disk []string `help:"Data disk description, from the 1st data disk to the last one, empty string if no change for this data disk"`
InstanceType string `help:"Instance Type, e.g. S2.SMALL2 for qcloud"`

2
vendor/modules.txt vendored
View File

@@ -1458,7 +1458,7 @@ sigs.k8s.io/structured-merge-diff/v4/value
# sigs.k8s.io/yaml v1.2.0
## explicit; go 1.12
sigs.k8s.io/yaml
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20231117073513-e4f90b4cabe4
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20231120065010-32185e2427ba
## explicit; go 1.18
yunion.io/x/cloudmux/pkg/apis
yunion.io/x/cloudmux/pkg/apis/billing

View File

@@ -175,6 +175,7 @@ type SManagedVMCreateConfig struct {
type SManagedVMChangeConfig struct {
Cpu int
CpuSocket int
MemoryMB int
InstanceType string
}

View File

@@ -346,6 +346,7 @@ type ICloudVM interface {
GetSerialOutput(port int) (string, error) // 目前仅谷歌云windows机器会使用到此接口
GetCpuSockets() int
GetVcpuCount() int
GetVmemSizeMB() int //MB
GetBootOrder() string

View File

@@ -771,6 +771,7 @@ type SCreateVMParam struct {
Name string
Uuid string
OsName string
CpuSockets int
Cpu int
Mem int
Bios string
@@ -1056,14 +1057,19 @@ func (host *SHost) DoCreateVM(ctx context.Context, ds *SDatastore, params SCreat
version = "vmx-08"
}
if params.CpuSockets == 0 {
params.CpuSockets = 1
}
spec := types.VirtualMachineConfigSpec{
Name: name,
Version: version,
Uuid: params.Uuid,
GuestId: guestId,
NumCPUs: int32(params.Cpu),
MemoryMB: int64(params.Mem),
Firmware: firmware,
Name: name,
Version: version,
Uuid: params.Uuid,
GuestId: guestId,
NumCPUs: int32(params.Cpu),
NumCoresPerSocket: int32(params.CpuSockets),
MemoryMB: int64(params.Mem),
Firmware: firmware,
CpuHotAddEnabled: &True,
CpuHotRemoveEnabled: &True,
@@ -1288,11 +1294,15 @@ func (host *SHost) CloneVM(ctx context.Context, from *SVirtualMachine, snapshot
if len(params.Uuid) != 0 {
name = params.Uuid
}
if params.CpuSockets == 0 {
params.CpuSockets = 1
}
spec := types.VirtualMachineConfigSpec{
Name: name,
Uuid: params.Uuid,
NumCPUs: int32(params.Cpu),
MemoryMB: int64(params.Mem),
Name: name,
Uuid: params.Uuid,
NumCPUs: int32(params.Cpu),
NumCoresPerSocket: int32(params.CpuSockets),
MemoryMB: int64(params.Mem),
CpuHotAddEnabled: &True,
CpuHotRemoveEnabled: &True,

View File

@@ -388,6 +388,14 @@ func (svm *SVirtualMachine) GetIEIP() (cloudprovider.ICloudEIP, error) {
return nil, nil
}
func (svm *SVirtualMachine) GetCpuSockets() int {
vm := svm.getVirtualMachine()
if vm.Config != nil {
return int(vm.Config.Hardware.NumCoresPerSocket)
}
return 1
}
func (svm *SVirtualMachine) GetVcpuCount() int {
return int(svm.getVirtualMachine().Summary.Config.NumCpu)
}
@@ -761,20 +769,24 @@ func (svm *SVirtualMachine) acquireVmrcUrl() (*cloudprovider.ServerVncOutput, er
}
func (svm *SVirtualMachine) ChangeConfig(ctx context.Context, config *cloudprovider.SManagedVMChangeConfig) error {
return svm.doChangeConfig(ctx, int32(config.Cpu), int64(config.MemoryMB), "", "")
return svm.doChangeConfig(ctx, int32(config.Cpu), int32(config.CpuSocket), int64(config.MemoryMB), "", "")
}
func (svm *SVirtualMachine) GetVersion() string {
return svm.getVirtualMachine().Config.Version
}
func (svm *SVirtualMachine) doChangeConfig(ctx context.Context, ncpu int32, vmemMB int64, guestId string, version string) error {
func (svm *SVirtualMachine) doChangeConfig(ctx context.Context, ncpu, cpuSockets int32, vmemMB int64, guestId string, version string) error {
changed := false
configSpec := types.VirtualMachineConfigSpec{}
if int(ncpu) != svm.GetVcpuCount() {
configSpec.NumCPUs = ncpu
changed = true
}
if cpuSockets > 0 && int(cpuSockets) != svm.GetCpuSockets() {
configSpec.NumCoresPerSocket = cpuSockets
changed = true
}
if int(vmemMB) != svm.GetVmemSizeMB() {
configSpec.MemoryMB = vmemMB
changed = true

View File

@@ -31,6 +31,10 @@ func (instance *SInstanceBase) GetIHostId() string {
return ""
}
func (instance *SInstanceBase) GetCpuSockets() int {
return 1
}
func (instance *SInstanceBase) GetSerialOutput(port int) (string, error) {
return "", cloudprovider.ErrNotImplemented
}

View File

@@ -34,6 +34,7 @@ type SInstance struct {
Hostname string
SecurityGroupIds []string
VcpuCount int
CpuSockets int
VmemSizeMb int
BootOrder string
Vga string
@@ -168,6 +169,10 @@ func (self *SInstance) AllocatePublicIpAddress() (string, error) {
return "", cloudprovider.ErrNotSupported
}
func (self *SInstance) GetCpuSockets() int {
return self.CpuSockets
}
func (self *SInstance) GetVcpuCount() int {
return self.VcpuCount
}