mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/yunionio/cloudpods.git
synced 2026-09-20 08:03:53 +08:00
299 lines
9.2 KiB
Go
299 lines
9.2 KiB
Go
// 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 guestdrivers
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"yunion.io/x/jsonutils"
|
|
"yunion.io/x/log"
|
|
"yunion.io/x/pkg/errors"
|
|
"yunion.io/x/pkg/utils"
|
|
|
|
api "yunion.io/x/onecloud/pkg/apis/compute"
|
|
"yunion.io/x/onecloud/pkg/cloudcommon/db/quotas"
|
|
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
|
"yunion.io/x/onecloud/pkg/compute/models"
|
|
"yunion.io/x/onecloud/pkg/compute/options"
|
|
"yunion.io/x/onecloud/pkg/httperrors"
|
|
"yunion.io/x/onecloud/pkg/mcclient"
|
|
"yunion.io/x/onecloud/pkg/multicloud/esxi"
|
|
"yunion.io/x/onecloud/pkg/util/billing"
|
|
"yunion.io/x/onecloud/pkg/util/httputils"
|
|
"yunion.io/x/onecloud/pkg/util/rbacutils"
|
|
)
|
|
|
|
type SESXiGuestDriver struct {
|
|
SManagedVirtualizedGuestDriver
|
|
}
|
|
|
|
func init() {
|
|
driver := SESXiGuestDriver{}
|
|
models.RegisterGuestDriver(&driver)
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) DoScheduleCPUFilter() bool { return true }
|
|
|
|
func (self *SESXiGuestDriver) DoScheduleMemoryFilter() bool { return true }
|
|
|
|
func (self *SESXiGuestDriver) DoScheduleSKUFilter() bool { return false }
|
|
|
|
func (self *SESXiGuestDriver) GetHypervisor() string {
|
|
return api.HYPERVISOR_ESXI
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) GetProvider() string {
|
|
return api.CLOUD_PROVIDER_VMWARE
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) GetComputeQuotaKeys(scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider, brand string) models.SComputeResourceKeys {
|
|
keys := models.SComputeResourceKeys{}
|
|
keys.SBaseQuotaKeys = quotas.OwnerIdQuotaKeys(scope, ownerId)
|
|
keys.CloudEnv = api.CLOUD_ENV_ON_PREMISE
|
|
keys.Provider = api.CLOUD_PROVIDER_VMWARE
|
|
// ignore brand
|
|
// ignore hypervisor keys.Hypervisor = api.HYPERVISOR_ESXI
|
|
return keys
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) GetDefaultSysDiskBackend() string {
|
|
return api.STORAGE_LOCAL
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) GetMinimalSysDiskSizeGb() int {
|
|
return options.Options.DefaultDiskSizeMB / 1024
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) RequestSyncSecgroupsOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
|
|
return nil // do nothing, not support securitygroup
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) GetMaxSecurityGroupCount() int {
|
|
//暂不支持绑定安全组
|
|
return 0
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) GetDetachDiskStatus() ([]string, error) {
|
|
return []string{api.VM_READY, api.VM_RUNNING}, nil
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) GetAttachDiskStatus() ([]string, error) {
|
|
return []string{api.VM_READY, api.VM_RUNNING}, nil
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) GetChangeConfigStatus() ([]string, error) {
|
|
return []string{api.VM_READY}, nil
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) CanKeepDetachDisk() bool {
|
|
return false
|
|
}
|
|
|
|
// func (self *SESXiGuestDriver) RequestDeleteDetachedDisk(ctx context.Context, disk *models.SDisk, task taskman.ITask, isPurge bool) error {
|
|
// err := disk.RealDelete(ctx, task.GetUserCred())
|
|
// if err != nil {
|
|
// return err
|
|
// }
|
|
// task.ScheduleRun(nil)
|
|
// return nil
|
|
// }
|
|
|
|
func (self *SESXiGuestDriver) RequestGuestHotAddIso(ctx context.Context, guest *models.SGuest, path string, boot bool, task taskman.ITask) error {
|
|
task.ScheduleRun(nil)
|
|
return nil
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) GetRebuildRootStatus() ([]string, error) {
|
|
return []string{api.VM_READY}, nil
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) GetDeployStatus() ([]string, error) {
|
|
return []string{api.VM_READY}, nil
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) ValidateCreateEip(ctx context.Context, userCred mcclient.TokenCredential, data jsonutils.JSONObject) error {
|
|
return httperrors.NewInputParameterError("%s not support create eip", self.GetHypervisor())
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) ValidateResizeDisk(guest *models.SGuest, disk *models.SDisk, storage *models.SStorage) error {
|
|
if !utils.IsInStringArray(guest.Status, []string{api.VM_READY}) {
|
|
return fmt.Errorf("Cannot resize disk when guest in status %s", guest.Status)
|
|
}
|
|
if disk.DiskType == api.DISK_TYPE_SYS {
|
|
return fmt.Errorf("Cannot resize system disk")
|
|
}
|
|
/*if !utils.IsInStringArray(storage.StorageType, []string{models.STORAGE_PUBLIC_CLOUD, models.STORAGE_CLOUD_SSD, models.STORAGE_CLOUD_EFFICIENCY}) {
|
|
return fmt.Errorf("Cannot resize %s disk", storage.StorageType)
|
|
}*/
|
|
return nil
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) GetJsonDescAtHost(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, host *models.SHost) jsonutils.JSONObject {
|
|
return guest.GetJsonDescAtHypervisor(ctx, host)
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) RequestDeployGuestOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
|
|
config, err := guest.GetDeployConfigOnHost(ctx, task.GetUserCred(), host, task.GetParams())
|
|
if err != nil {
|
|
log.Errorf("GetDeployConfigOnHost error: %v", err)
|
|
return err
|
|
}
|
|
log.Debugf("RequestDeployGuestOnHost: %s", config)
|
|
|
|
if !host.IsEsxiAgentReady() {
|
|
return fmt.Errorf("No ESXi agent host")
|
|
}
|
|
|
|
diskCat := guest.CategorizeDisks()
|
|
if diskCat.Root == nil {
|
|
return fmt.Errorf("no root disk???")
|
|
}
|
|
storage := diskCat.Root.GetStorage()
|
|
if storage == nil {
|
|
return fmt.Errorf("root disk has no storage???")
|
|
}
|
|
|
|
config.Add(jsonutils.NewString(host.AccessIp), "host_ip")
|
|
config.Add(jsonutils.NewString(guest.Id), "guest_id")
|
|
extId := guest.Id
|
|
if len(guest.ExternalId) > 0 {
|
|
extId = guest.ExternalId
|
|
}
|
|
config.Add(jsonutils.NewString(extId), "guest_ext_id")
|
|
|
|
accessInfo, err := host.GetCloudaccount().GetVCenterAccessInfo(storage.ExternalId)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
config.Add(jsonutils.Marshal(accessInfo), "datastore")
|
|
|
|
url := "/disks/agent/deploy"
|
|
|
|
body := jsonutils.NewDict()
|
|
body.Add(config, "disk")
|
|
|
|
header := task.GetTaskRequestHeader()
|
|
|
|
_, err = host.EsxiRequest(ctx, httputils.POST, url, header, body)
|
|
return err
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) RqeuestSuspendOnHost(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
|
|
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
|
|
host := guest.GetHost()
|
|
if host == nil {
|
|
return nil, errors.Error("fail to get host of guest")
|
|
}
|
|
ihost, err := host.GetIHost()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
ivm, err := ihost.GetIVMById(guest.GetExternalId())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
vm := ivm.(*esxi.SVirtualMachine)
|
|
err = vm.SuspendVM(ctx)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "VM.SuspendVM for vmware")
|
|
}
|
|
return nil, nil
|
|
})
|
|
return nil
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) RqeuestResumeOnHost(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
|
|
taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
|
|
host := guest.GetHost()
|
|
if host == nil {
|
|
return nil, errors.Error("fail to get host of guest")
|
|
}
|
|
ihost, err := host.GetIHost()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
ivm, err := ihost.GetIVMById(guest.GetExternalId())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
vm := ivm.(*esxi.SVirtualMachine)
|
|
err = vm.ResumeVM(ctx)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "VM.Resume for VMware")
|
|
}
|
|
return nil, nil
|
|
})
|
|
return nil
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) OnGuestDeployTaskDataReceived(ctx context.Context, guest *models.SGuest, task taskman.ITask, data jsonutils.JSONObject) error {
|
|
|
|
if data.Contains("host_ip") {
|
|
hostIp, _ := data.GetString("host_ip")
|
|
host, err := models.HostManager.GetHostByIp(hostIp)
|
|
if err != nil {
|
|
log.Errorf("fail to find host with IP %s: %s", hostIp, err)
|
|
return err
|
|
}
|
|
if host.Id != guest.HostId {
|
|
models.HostManager.ClearSchedDescCache(host.Id)
|
|
models.HostManager.ClearSchedDescCache(guest.HostId)
|
|
guest.OnScheduleToHost(ctx, task.GetUserCred(), host.Id)
|
|
}
|
|
}
|
|
|
|
return self.SManagedVirtualizedGuestDriver.OnGuestDeployTaskDataReceived(ctx, guest, task, data)
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) AllowReconfigGuest() bool {
|
|
return true
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) DoGuestCreateDisksTask(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
|
|
subtask, err := taskman.TaskManager.NewTask(ctx, "ESXiGuestCreateDiskTask", guest, task.GetUserCred(), task.GetParams(), task.GetTaskId(), "", nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
subtask.ScheduleRun(nil)
|
|
return nil
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) RequestRenewInstance(guest *models.SGuest, bc billing.SBillingCycle) (time.Time, error) {
|
|
return time.Time{}, nil
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) IsSupportEip() bool {
|
|
return false
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) RequestAssociateEip(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, eip *models.SElasticip, task taskman.ITask) error {
|
|
return fmt.Errorf("ESXiGuestDriver not support associate eip")
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) CancelExpireTime(
|
|
ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest) error {
|
|
return guest.CancelExpireTime(ctx, userCred)
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) IsSupportPostpaidExpire() bool {
|
|
return true
|
|
}
|
|
|
|
func (self *SESXiGuestDriver) IsSupportCdrom(guest *models.SGuest) (bool, error) {
|
|
return false, nil
|
|
}
|