| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581 |
- // 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 esxi
- import (
- "context"
- "fmt"
- "path"
- "path/filepath"
- "strings"
- "time"
- "github.com/vmware/govmomi/vim25/types"
- "yunion.io/x/log"
- "yunion.io/x/pkg/errors"
- api "yunion.io/x/cloudmux/pkg/apis/compute"
- "yunion.io/x/cloudmux/pkg/cloudprovider"
- "yunion.io/x/cloudmux/pkg/multicloud"
- )
- var driverMap = map[string]string{
- "ahci": "sata",
- "parascsi": "pvscsi",
- "buslogic": "scsi",
- "lsilogic": "scsi",
- "lsilogicsas": "scsi",
- }
- type SVirtualDisk struct {
- multicloud.SDisk
- multicloud.STagBase
- SVirtualDevice
- IsRoot bool
- }
- func NewVirtualDisk(vm *SVirtualMachine, dev types.BaseVirtualDevice, index int) SVirtualDisk {
- isRoot := dev.GetVirtualDevice().DeviceInfo.GetDescription().Label == rootDiskMark
- return SVirtualDisk{
- SDisk: multicloud.SDisk{},
- SVirtualDevice: NewVirtualDevice(vm, dev, index),
- IsRoot: isRoot,
- }
- }
- func (disk *SVirtualDisk) getVirtualDisk() *types.VirtualDisk {
- return disk.dev.(*types.VirtualDisk)
- }
- type IDiskBackingInfo interface {
- GetParent() IDiskBackingInfo
- GetUuid() string
- GetDiskMode() string
- GetPreallocation() string
- GetWriteThrough() bool
- GetFileName() string
- GetDatastore() *types.ManagedObjectReference
- }
- type sVirtualDiskFlatVer2BackingInfo struct {
- info *types.VirtualDiskFlatVer2BackingInfo
- }
- func (s *sVirtualDiskFlatVer2BackingInfo) GetParent() IDiskBackingInfo {
- if s.info.Parent != nil {
- return &sVirtualDiskFlatVer2BackingInfo{
- info: s.info.Parent,
- }
- }
- return nil
- }
- func (s *sVirtualDiskFlatVer2BackingInfo) GetUuid() string {
- return s.info.Uuid
- }
- func (s *sVirtualDiskFlatVer2BackingInfo) GetPreallocation() string {
- if s.info.ThinProvisioned != nil {
- if *s.info.ThinProvisioned {
- return api.DISK_PREALLOCATION_METADATA
- }
- if s.info.EagerlyScrub == nil || !*s.info.EagerlyScrub {
- return api.DISK_PREALLOCATION_FALLOC
- }
- return api.DISK_PREALLOCATION_FULL
- }
- return api.DISK_PREALLOCATION_METADATA
- }
- func (s *sVirtualDiskFlatVer2BackingInfo) GetDiskMode() string {
- return s.info.DiskMode
- }
- func (s *sVirtualDiskFlatVer2BackingInfo) GetWriteThrough() bool {
- if s.info.WriteThrough != nil && *s.info.WriteThrough == true {
- return true
- } else {
- return false
- }
- }
- func (s *sVirtualDiskFlatVer2BackingInfo) GetFileName() string {
- return s.info.FileName
- }
- func (s *sVirtualDiskFlatVer2BackingInfo) GetDatastore() *types.ManagedObjectReference {
- return s.info.Datastore
- }
- type sVirtualDiskSparseVer2BackingInfo struct {
- info *types.VirtualDiskSparseVer2BackingInfo
- }
- func (s *sVirtualDiskSparseVer2BackingInfo) GetParent() IDiskBackingInfo {
- if s.info.Parent != nil {
- return &sVirtualDiskSparseVer2BackingInfo{
- info: s.info.Parent,
- }
- }
- return nil
- }
- func (s *sVirtualDiskSparseVer2BackingInfo) GetUuid() string {
- return s.info.Uuid
- }
- func (s *sVirtualDiskSparseVer2BackingInfo) GetPreallocation() string {
- return api.DISK_PREALLOCATION_METADATA
- }
- func (s *sVirtualDiskSparseVer2BackingInfo) GetDiskMode() string {
- return s.info.DiskMode
- }
- func (s *sVirtualDiskSparseVer2BackingInfo) GetWriteThrough() bool {
- if s.info.WriteThrough != nil && *s.info.WriteThrough == true {
- return true
- } else {
- return false
- }
- }
- func (s *sVirtualDiskSparseVer2BackingInfo) GetFileName() string {
- return s.info.FileName
- }
- func (s *sVirtualDiskSparseVer2BackingInfo) GetDatastore() *types.ManagedObjectReference {
- return s.info.Datastore
- }
- type sVirtualDiskRawDiskMappingVer1BackingInfo struct {
- info *types.VirtualDiskRawDiskMappingVer1BackingInfo
- }
- func (s *sVirtualDiskRawDiskMappingVer1BackingInfo) GetParent() IDiskBackingInfo {
- if s.info.Parent != nil {
- return &sVirtualDiskRawDiskMappingVer1BackingInfo{
- info: s.info.Parent,
- }
- }
- return nil
- }
- func (s *sVirtualDiskRawDiskMappingVer1BackingInfo) GetUuid() string {
- return s.info.Uuid
- }
- func (s *sVirtualDiskRawDiskMappingVer1BackingInfo) GetDiskMode() string {
- return s.info.DiskMode
- }
- func (s *sVirtualDiskRawDiskMappingVer1BackingInfo) GetPreallocation() string {
- return api.DISK_PREALLOCATION_METADATA
- }
- func (s *sVirtualDiskRawDiskMappingVer1BackingInfo) GetWriteThrough() bool {
- return false
- }
- func (s *sVirtualDiskRawDiskMappingVer1BackingInfo) GetFileName() string {
- return s.info.FileName
- }
- func (s *sVirtualDiskRawDiskMappingVer1BackingInfo) GetDatastore() *types.ManagedObjectReference {
- return s.info.Datastore
- }
- type sVirtualDiskSparseVer1BackingInfo struct {
- info *types.VirtualDiskSparseVer1BackingInfo
- }
- func (s *sVirtualDiskSparseVer1BackingInfo) GetParent() IDiskBackingInfo {
- if s.info.Parent != nil {
- return &sVirtualDiskSparseVer1BackingInfo{
- info: s.info.Parent,
- }
- }
- return nil
- }
- func (s *sVirtualDiskSparseVer1BackingInfo) GetUuid() string {
- return s.info.Datastore.String() + s.info.FileName
- }
- func (s *sVirtualDiskSparseVer1BackingInfo) GetPreallocation() string {
- return api.DISK_PREALLOCATION_METADATA
- }
- func (s *sVirtualDiskSparseVer1BackingInfo) GetDiskMode() string {
- return s.info.DiskMode
- }
- func (s *sVirtualDiskSparseVer1BackingInfo) GetWriteThrough() bool {
- if s.info.WriteThrough != nil && *s.info.WriteThrough == true {
- return true
- } else {
- return false
- }
- }
- func (s *sVirtualDiskSparseVer1BackingInfo) GetFileName() string {
- return s.info.FileName
- }
- func (s *sVirtualDiskSparseVer1BackingInfo) GetDatastore() *types.ManagedObjectReference {
- return s.info.Datastore
- }
- type sVirtualDiskFlatVer1BackingInfo struct {
- info *types.VirtualDiskFlatVer1BackingInfo
- }
- func (s *sVirtualDiskFlatVer1BackingInfo) GetParent() IDiskBackingInfo {
- if s.info.Parent != nil {
- return &sVirtualDiskFlatVer1BackingInfo{
- info: s.info.Parent,
- }
- }
- return nil
- }
- func (s *sVirtualDiskFlatVer1BackingInfo) GetUuid() string {
- return s.info.Datastore.String() + s.info.FileName
- }
- func (s *sVirtualDiskFlatVer1BackingInfo) GetDiskMode() string {
- return s.info.DiskMode
- }
- func (s *sVirtualDiskFlatVer1BackingInfo) GetPreallocation() string {
- return api.DISK_PREALLOCATION_METADATA
- }
- func (s *sVirtualDiskFlatVer1BackingInfo) GetWriteThrough() bool {
- if s.info.WriteThrough != nil && *s.info.WriteThrough == true {
- return true
- } else {
- return false
- }
- }
- func (s *sVirtualDiskFlatVer1BackingInfo) GetFileName() string {
- return s.info.FileName
- }
- func (s *sVirtualDiskFlatVer1BackingInfo) GetDatastore() *types.ManagedObjectReference {
- return s.info.Datastore
- }
- func (disk *SVirtualDisk) getBackingInfo() IDiskBackingInfo {
- backing := disk.getVirtualDisk().Backing
- switch backing.(type) {
- case *types.VirtualDiskFlatVer2BackingInfo:
- return &sVirtualDiskFlatVer2BackingInfo{
- info: backing.(*types.VirtualDiskFlatVer2BackingInfo),
- }
- case *types.VirtualDeviceFileBackingInfo:
- case *types.VirtualDiskFlatVer1BackingInfo:
- return &sVirtualDiskFlatVer1BackingInfo{
- info: backing.(*types.VirtualDiskFlatVer1BackingInfo),
- }
- case *types.VirtualDiskLocalPMemBackingInfo:
- case *types.VirtualDiskRawDiskMappingVer1BackingInfo:
- return &sVirtualDiskRawDiskMappingVer1BackingInfo{
- info: backing.(*types.VirtualDiskRawDiskMappingVer1BackingInfo),
- }
- case *types.VirtualDiskSeSparseBackingInfo:
- case *types.VirtualDiskSparseVer1BackingInfo:
- return &sVirtualDiskSparseVer1BackingInfo{
- info: backing.(*types.VirtualDiskSparseVer1BackingInfo),
- }
- case *types.VirtualDiskSparseVer2BackingInfo:
- return &sVirtualDiskSparseVer2BackingInfo{
- info: backing.(*types.VirtualDiskSparseVer2BackingInfo),
- }
- case *types.VirtualFloppyImageBackingInfo:
- case *types.VirtualNVDIMMBackingInfo:
- case *types.VirtualParallelPortFileBackingInfo:
- case *types.VirtualSerialPortFileBackingInfo:
- case *types.VirtualCdromIsoBackingInfo:
- }
- log.Fatalf("unsupported backing info %T", backing)
- return nil
- }
- func (disk *SVirtualDisk) GetId() string {
- backing := disk.getBackingInfo()
- return backing.GetUuid()
- }
- func (disk *SVirtualDisk) MatchId(id string) bool {
- vmid := disk.vm.GetGlobalId()
- if !strings.HasPrefix(id, vmid) {
- return false
- }
- backingUuid := id[len(vmid)+1:]
- backing := disk.getBackingInfo()
- for backing != nil {
- if backing.GetUuid() == backingUuid {
- return true
- }
- backing = backing.GetParent()
- }
- return false
- }
- func (disk *SVirtualDisk) GetName() string {
- backing := disk.getBackingInfo()
- return path.Base(backing.GetFileName())
- }
- func (disk *SVirtualDisk) GetGlobalId() string {
- return fmt.Sprintf("%s-%s", disk.vm.GetGlobalId(), disk.GetId())
- }
- func (disk *SVirtualDisk) GetStatus() string {
- return api.DISK_READY
- }
- func (disk *SVirtualDisk) Refresh() error {
- return nil
- }
- func (disk *SVirtualDisk) IsEmulated() bool {
- return false
- }
- func (disk *SVirtualDisk) GetDiskSizeMB() int {
- capa := disk.getVirtualDisk().CapacityInBytes
- if capa == 0 {
- capa = disk.getVirtualDisk().CapacityInKB * 1024
- }
- return int(capa / 1024 / 1024)
- }
- func (disk *SVirtualDisk) GetAccessPath() string {
- istore, err := disk.GetIStorage()
- if err != nil {
- log.Errorf("disk.GetIStorage fail %s", err)
- return ""
- }
- ds := istore.(*SDatastore)
- return ds.GetFullPath(disk.getBackingInfo().GetFileName())
- }
- func (disk *SVirtualDisk) GetDiskFormat() string {
- return "vmdk"
- }
- func (disk *SVirtualDisk) GetIStorage() (cloudprovider.ICloudStorage, error) {
- dsObj := disk.getBackingInfo().GetDatastore()
- dc, err := disk.vm.GetDatacenter()
- if err != nil {
- return nil, errors.Wrapf(err, "GetDatacenter")
- }
- istorage, err := dc.GetIStorageByMoId(moRefId(*dsObj))
- if err != nil {
- return nil, err
- }
- return istorage, nil
- }
- func (disk *SVirtualDisk) GetIStorageId() string {
- storage, err := disk.GetIStorage()
- if err != nil {
- return ""
- }
- return storage.GetGlobalId()
- }
- func (disk *SVirtualDisk) GetIsAutoDelete() bool {
- return true
- }
- func (disk *SVirtualDisk) GetTemplateId() string {
- backing := disk.getBackingInfo()
- if backing.GetParent() != nil {
- return path.Base(backing.GetParent().GetFileName())
- }
- return ""
- }
- func (disk *SVirtualDisk) GetDiskType() string {
- if disk.IsRoot {
- return api.DISK_TYPE_SYS
- }
- return api.DISK_TYPE_DATA
- }
- func (disk *SVirtualDisk) GetFsFormat() string {
- return ""
- }
- func (disk *SVirtualDisk) getDiskMode() string {
- backing := disk.getBackingInfo()
- return backing.GetDiskMode()
- }
- func (disk *SVirtualDisk) GetIsNonPersistent() bool {
- return disk.getDiskMode() == "independent_nonpersistent"
- }
- func (disk *SVirtualDisk) GetDriver() string {
- controller := disk.vm.getVdev(disk.getControllerKey())
- name := controller.GetDriver()
- name = strings.Replace(name, "controller", "", -1)
- if driver, ok := driverMap[name]; ok {
- return driver
- }
- return name
- }
- func (disk *SVirtualDisk) GetCacheMode() string {
- backing := disk.getBackingInfo()
- if backing.GetWriteThrough() {
- return "writethrough"
- } else {
- return "none"
- }
- }
- func (disk *SVirtualDisk) GetMountpoint() string {
- return ""
- }
- func (disk *SVirtualDisk) GetPreallocation() string {
- backing := disk.getBackingInfo()
- return backing.GetPreallocation()
- }
- func (disk *SVirtualDisk) Delete(ctx context.Context) error {
- istorage, err := disk.GetIStorage()
- if err != nil {
- return errors.Wrapf(err, "GetIStorage")
- }
- ds := istorage.(*SDatastore)
- return ds.Delete2(ctx, disk.getBackingInfo().GetFileName(), false, false)
- }
- func (disk *SVirtualDisk) CreateISnapshot(ctx context.Context, name string, desc string) (cloudprovider.ICloudSnapshot, error) {
- return nil, cloudprovider.ErrNotImplemented
- }
- func (disk *SVirtualDisk) GetISnapshot(idStr string) (cloudprovider.ICloudSnapshot, error) {
- return nil, cloudprovider.ErrNotImplemented
- }
- func (disk *SVirtualDisk) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
- return nil, cloudprovider.ErrNotImplemented
- }
- func (disk *SVirtualDisk) Resize(ctx context.Context, newSizeMb int64) error {
- ndisk := disk.getVirtualDisk()
- ndisk.CapacityInKB = newSizeMb * 1024
- devSpec := types.VirtualDeviceConfigSpec{}
- devSpec.Device = ndisk
- devSpec.Operation = types.VirtualDeviceConfigSpecOperationEdit
- spec := types.VirtualMachineConfigSpec{}
- spec.DeviceChange = []types.BaseVirtualDeviceConfigSpec{&devSpec}
- vm := disk.vm.getVmObj()
- task, err := vm.Reconfigure(ctx, spec)
- if err != nil {
- return errors.Wrapf(err, "Reconfigure")
- }
- err = task.Wait(ctx)
- if err != nil {
- return errors.Wrapf(err, "task.Wait")
- }
- return err
- }
- /*
- func (disk *SVirtualDisk) ResizePartition(ctx context.Context, accessInfo vcenter.SVCenterAccessInfo) error {
- diskPath := disk.GetFilename()
- vmref := disk.vm.GetMoid()
- diskInfo := deployapi.DiskInfo{
- Path: diskPath,
- }
- vddkInfo := deployapi.VDDKConInfo{
- Host: accessInfo.Host,
- Port: int32(accessInfo.Port),
- User: accessInfo.Account,
- Passwd: accessInfo.Password,
- Vmref: vmref,
- }
- _, err := deployclient.GetDeployClient().ResizeFs(ctx, &deployapi.ResizeFsParams{
- DiskInfo: &diskInfo,
- Hypervisor: compute.HYPERVISOR_ESXI,
- VddkInfo: &vddkInfo,
- })
- if err != nil {
- return errors.Wrap(err, "unable to ResizeFs")
- }
- return nil
- }
- */
- func (disk *SVirtualDisk) Reset(ctx context.Context, snapshotId string) (string, error) {
- return "", cloudprovider.ErrNotImplemented
- }
- func (disk *SVirtualDisk) GetBillingType() string {
- return ""
- }
- // GetCreatedAt return create time by getting the Data of file stored at disk.GetAccessPath
- func (disk *SVirtualDisk) GetCreatedAt() time.Time {
- path, name := disk.GetAccessPath(), disk.GetFilename()
- storage, err := disk.GetIStorage()
- if err != nil {
- return time.Time{}
- }
- ds := storage.(*SDatastore)
- files, err := ds.ListDir(context.Background(), filepath.Dir(path))
- if err != nil {
- return time.Time{}
- }
- for _, file := range files {
- if file.Name == name {
- return file.Date
- }
- }
- return time.Time{}
- }
- func (disk *SVirtualDisk) GetExpiredAt() time.Time {
- return time.Time{}
- }
- func (disk *SVirtualDisk) Rebuild(ctx context.Context) error {
- return disk.vm.rebuildDisk(ctx, disk, "", false)
- }
- func (disk *SVirtualDisk) GetProjectId() string {
- return disk.vm.GetProjectId()
- }
- func (disk *SVirtualDisk) GetFilename() string {
- return disk.getBackingInfo().GetFileName()
- }
|