yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/esxi/template.go (about)

     1  // Copyright 2019 Yunion
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package esxi
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"strings"
    21  	"time"
    22  
    23  	"yunion.io/x/log"
    24  	"yunion.io/x/pkg/errors"
    25  
    26  	api "yunion.io/x/cloudmux/pkg/apis/compute"
    27  	"yunion.io/x/cloudmux/pkg/cloudprovider"
    28  	"yunion.io/x/cloudmux/pkg/multicloud"
    29  )
    30  
    31  type SVMTemplate struct {
    32  	multicloud.SImageBase
    33  	multicloud.STagBase
    34  	cache *SDatastoreImageCache
    35  	vm    *SVirtualMachine
    36  	uuid  string
    37  }
    38  
    39  func NewVMTemplate(vm *SVirtualMachine, cache *SDatastoreImageCache) *SVMTemplate {
    40  	return &SVMTemplate{
    41  		cache: cache,
    42  		vm:    vm,
    43  		uuid:  vm.GetGlobalId(),
    44  	}
    45  }
    46  
    47  const splitStr = "/"
    48  
    49  func toTemplateUuid(templateId string) string {
    50  	ids := strings.Split(templateId, splitStr)
    51  	if len(ids) == 1 {
    52  		return ids[0]
    53  	}
    54  	return ids[1]
    55  }
    56  
    57  func toTemplateId(providerId string, templateUuid string) string {
    58  	return fmt.Sprintf("%s%s%s", providerId, splitStr, templateUuid)
    59  }
    60  
    61  func (t *SVMTemplate) GetId() string {
    62  	providerId := t.vm.manager.cpcfg.Id
    63  	return toTemplateId(providerId, t.uuid)
    64  }
    65  
    66  func (t *SVMTemplate) GetName() string {
    67  	return t.vm.GetName()
    68  }
    69  
    70  func (t *SVMTemplate) GetGlobalId() string {
    71  	return t.GetId()
    72  }
    73  
    74  func (t *SVMTemplate) GetStatus() string {
    75  	ihosts, err := t.cache.datastore.GetAttachedHosts()
    76  	if err != nil {
    77  		return api.CACHED_IMAGE_STATUS_CACHE_FAILED
    78  	}
    79  	for _, ihost := range ihosts {
    80  		host := ihost.(*SHost)
    81  		_, err := host.GetTemplateVMById(t.uuid)
    82  		if err == nil {
    83  			return api.CACHED_IMAGE_STATUS_ACTIVE
    84  		}
    85  		if errors.Cause(err) != cloudprovider.ErrNotFound {
    86  			log.Errorf("fail to find templatevm %q: %v", t.uuid, err)
    87  			return api.CACHED_IMAGE_STATUS_CACHE_FAILED
    88  		}
    89  	}
    90  	return api.CACHED_IMAGE_STATUS_CACHE_FAILED
    91  }
    92  
    93  func (t *SVMTemplate) Refresh() error {
    94  	vm, err := t.cache.host.GetTemplateVMById(t.uuid)
    95  	if errors.Cause(err) == cloudprovider.ErrNotFound {
    96  		return errors.Wrap(err, "no such vm template")
    97  	}
    98  	if err != nil {
    99  		return errors.Wrap(err, "SHost.GetTemplateVMById")
   100  	}
   101  	t.vm = vm
   102  	return nil
   103  }
   104  
   105  func (t *SVMTemplate) IsEmulated() bool {
   106  	return false
   107  }
   108  
   109  func (t *SVMTemplate) Delete(ctx context.Context) error {
   110  	vm, err := t.cache.host.GetTemplateVMById(t.uuid)
   111  	if errors.Cause(err) == cloudprovider.ErrNotFound {
   112  		return nil
   113  	}
   114  	if err != nil {
   115  		return errors.Wrapf(err, "fail to get template vm '%s'", t.uuid)
   116  	}
   117  	return vm.DeleteVM(ctx)
   118  }
   119  
   120  func (t *SVMTemplate) GetIStoragecache() cloudprovider.ICloudStoragecache {
   121  	return t.cache
   122  }
   123  
   124  func (t *SVMTemplate) GetSizeByte() int64 {
   125  	var sum int
   126  	for i := range t.vm.vdisks {
   127  		vdisk := t.vm.vdisks[i]
   128  		sum += vdisk.GetDiskSizeMB()
   129  	}
   130  	return int64(sum) * (1 << 20)
   131  }
   132  
   133  func (t *SVMTemplate) GetImageType() cloudprovider.TImageType {
   134  	return cloudprovider.ImageTypeSystem
   135  }
   136  
   137  func (t *SVMTemplate) GetImageStatus() string {
   138  	status := t.GetStatus()
   139  	if status == api.CACHED_IMAGE_STATUS_ACTIVE {
   140  		return cloudprovider.IMAGE_STATUS_ACTIVE
   141  	}
   142  	return cloudprovider.IMAGE_STATUS_DELETED
   143  }
   144  
   145  func (t *SVMTemplate) GetBios() cloudprovider.TBiosType {
   146  	return t.vm.GetBios()
   147  }
   148  
   149  func (t *SVMTemplate) GetOsType() cloudprovider.TOsType {
   150  	return t.vm.GetOsType()
   151  }
   152  
   153  func (t *SVMTemplate) GetOsDist() string {
   154  	return t.vm.GetOsDist()
   155  }
   156  
   157  func (t *SVMTemplate) GetOsVersion() string {
   158  	return t.vm.GetOsVersion()
   159  }
   160  
   161  func (t *SVMTemplate) GetOsLang() string {
   162  	return t.vm.GetOsLang()
   163  }
   164  
   165  func (t *SVMTemplate) GetOsArch() string {
   166  	return t.vm.GetOsArch()
   167  }
   168  
   169  func (t *SVMTemplate) GetFullOsName() string {
   170  	return t.vm.GetFullOsName()
   171  }
   172  
   173  func (t *SVMTemplate) GetMinOsDiskSizeGb() int {
   174  	return int(t.GetSizeByte() / (1 << 30))
   175  }
   176  
   177  func (t *SVMTemplate) GetMinRamSizeMb() int {
   178  	return 0
   179  }
   180  
   181  func (t *SVMTemplate) GetImageFormat() string {
   182  	return "vmdk"
   183  }
   184  
   185  // GetCreatedAt return vm's create time by getting the sys disk's create time
   186  func (t *SVMTemplate) GetCreatedAt() time.Time {
   187  	if len(t.vm.vdisks) == 0 {
   188  		return time.Time{}
   189  	}
   190  	return t.vm.vdisks[0].GetCreatedAt()
   191  }
   192  
   193  func (t *SVMTemplate) GetSubImages() []cloudprovider.SSubImage {
   194  	subImages := make([]cloudprovider.SSubImage, 0, len(t.vm.vdisks))
   195  	for i := range t.vm.vdisks {
   196  		vdisk := t.vm.vdisks[i]
   197  		sizeMb := vdisk.GetDiskSizeMB()
   198  		subImages = append(subImages, cloudprovider.SSubImage{
   199  			Index:     i,
   200  			SizeBytes: int64(sizeMb) * (1 << 20),
   201  			MinDiskMB: sizeMb,
   202  			MinRamMb:  0,
   203  		})
   204  	}
   205  	return subImages
   206  }