template.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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. package esxi
  15. import (
  16. "context"
  17. "fmt"
  18. "strings"
  19. "time"
  20. "yunion.io/x/log"
  21. "yunion.io/x/pkg/errors"
  22. "yunion.io/x/pkg/util/imagetools"
  23. api "yunion.io/x/cloudmux/pkg/apis/compute"
  24. "yunion.io/x/cloudmux/pkg/cloudprovider"
  25. "yunion.io/x/cloudmux/pkg/multicloud"
  26. )
  27. type SVMTemplate struct {
  28. multicloud.SImageBase
  29. multicloud.STagBase
  30. cache *SDatastoreImageCache
  31. vm *SVirtualMachine
  32. uuid string
  33. }
  34. func NewVMTemplate(vm *SVirtualMachine, cache *SDatastoreImageCache) *SVMTemplate {
  35. return &SVMTemplate{
  36. cache: cache,
  37. vm: vm,
  38. uuid: vm.GetGlobalId(),
  39. }
  40. }
  41. const splitStr = "/"
  42. func toTemplateUuid(templateId string) string {
  43. ids := strings.Split(templateId, splitStr)
  44. if len(ids) == 1 {
  45. return ids[0]
  46. }
  47. return ids[1]
  48. }
  49. func toTemplateId(providerId string, templateUuid string) string {
  50. return fmt.Sprintf("%s%s%s", providerId, splitStr, templateUuid)
  51. }
  52. func (t *SVMTemplate) GetId() string {
  53. providerId := t.vm.manager.cpcfg.Id
  54. return toTemplateId(providerId, t.uuid)
  55. }
  56. func (t *SVMTemplate) GetName() string {
  57. return t.vm.GetName()
  58. }
  59. func (t *SVMTemplate) GetGlobalId() string {
  60. return t.GetId()
  61. }
  62. func (t *SVMTemplate) GetStatus() string {
  63. ihosts, err := t.cache.datastore.GetAttachedHosts()
  64. if err != nil {
  65. log.Errorf("GetAttachedHosts for image %s error: %v", t.GetName(), err)
  66. return api.CACHED_IMAGE_STATUS_CACHE_FAILED
  67. }
  68. for _, ihost := range ihosts {
  69. host := ihost.(*SHost)
  70. _, err := host.GetTemplateVMById(t.uuid)
  71. if err == nil {
  72. return api.CACHED_IMAGE_STATUS_ACTIVE
  73. }
  74. if errors.Cause(err) != cloudprovider.ErrNotFound {
  75. log.Errorf("fail to find templatevm %q: %v", t.uuid, err)
  76. return api.CACHED_IMAGE_STATUS_CACHE_FAILED
  77. }
  78. }
  79. log.Errorf("empty host attached for image %s", t.GetName())
  80. return api.CACHED_IMAGE_STATUS_CACHE_FAILED
  81. }
  82. func (t *SVMTemplate) Refresh() error {
  83. vm, err := t.cache.host.GetTemplateVMById(t.uuid)
  84. if errors.Cause(err) == cloudprovider.ErrNotFound {
  85. return errors.Wrap(err, "no such vm template")
  86. }
  87. if err != nil {
  88. return errors.Wrap(err, "SHost.GetTemplateVMById")
  89. }
  90. t.vm = vm
  91. return nil
  92. }
  93. func (t *SVMTemplate) IsEmulated() bool {
  94. return false
  95. }
  96. func (t *SVMTemplate) Delete(ctx context.Context) error {
  97. vm, err := t.cache.host.GetTemplateVMById(t.uuid)
  98. if errors.Cause(err) == cloudprovider.ErrNotFound {
  99. return nil
  100. }
  101. if err != nil {
  102. return errors.Wrapf(err, "fail to get template vm '%s'", t.uuid)
  103. }
  104. return vm.DeleteVM(ctx)
  105. }
  106. func (t *SVMTemplate) GetIStoragecache() cloudprovider.ICloudStoragecache {
  107. return t.cache
  108. }
  109. func (t *SVMTemplate) GetSizeByte() int64 {
  110. for i := range t.vm.vdisks {
  111. vdisk := t.vm.vdisks[i]
  112. if vdisk.IsRoot {
  113. return int64(vdisk.GetDiskSizeMB()) * (1 << 20)
  114. }
  115. }
  116. return 0
  117. }
  118. func (t *SVMTemplate) GetImageType() cloudprovider.TImageType {
  119. return cloudprovider.ImageTypeSystem
  120. }
  121. func (t *SVMTemplate) GetImageStatus() string {
  122. status := t.GetStatus()
  123. if status == api.CACHED_IMAGE_STATUS_ACTIVE {
  124. return cloudprovider.IMAGE_STATUS_ACTIVE
  125. }
  126. return cloudprovider.IMAGE_STATUS_DELETED
  127. }
  128. func (t *SVMTemplate) GetBios() cloudprovider.TBiosType {
  129. return t.vm.GetBios()
  130. }
  131. func (t *SVMTemplate) GetOsType() cloudprovider.TOsType {
  132. return cloudprovider.TOsType(imagetools.NormalizeImageInfo(t.GetName(), "", "", "", "").OsType)
  133. }
  134. func (t *SVMTemplate) GetOsDist() string {
  135. return imagetools.NormalizeImageInfo(t.GetName(), "", "", "", "").OsDistro
  136. }
  137. func (t *SVMTemplate) GetOsVersion() string {
  138. return imagetools.NormalizeImageInfo(t.GetName(), "", "", "", "").OsVersion
  139. }
  140. func (t *SVMTemplate) GetOsLang() string {
  141. return imagetools.NormalizeImageInfo(t.GetName(), "", "", "", "").OsLang
  142. }
  143. func (t *SVMTemplate) GetOsArch() string {
  144. return imagetools.NormalizeImageInfo(t.GetName(), "", "", "", "").OsArch
  145. }
  146. func (t *SVMTemplate) GetFullOsName() string {
  147. return imagetools.NormalizeImageInfo(t.GetName(), "", "", "", "").OsFullVersion
  148. }
  149. func (t *SVMTemplate) GetMinOsDiskSizeGb() int {
  150. return int(t.GetSizeByte() / (1 << 30))
  151. }
  152. func (t *SVMTemplate) GetMinRamSizeMb() int {
  153. return 0
  154. }
  155. func (t *SVMTemplate) GetImageFormat() string {
  156. return "vmdk"
  157. }
  158. // GetCreatedAt return vm's create time by getting the sys disk's create time
  159. func (t *SVMTemplate) GetCreatedAt() time.Time {
  160. if len(t.vm.vdisks) == 0 {
  161. return time.Time{}
  162. }
  163. return t.vm.vdisks[0].GetCreatedAt()
  164. }
  165. func (t *SVMTemplate) GetSubImages() []cloudprovider.SSubImage {
  166. subImages := make([]cloudprovider.SSubImage, 0, len(t.vm.vdisks))
  167. for i := range t.vm.vdisks {
  168. vdisk := t.vm.vdisks[i]
  169. sizeMb := vdisk.GetDiskSizeMB()
  170. subImages = append(subImages, cloudprovider.SSubImage{
  171. Index: i,
  172. SizeBytes: int64(sizeMb) * (1 << 20),
  173. MinDiskMB: sizeMb,
  174. MinRamMb: 0,
  175. })
  176. }
  177. return subImages
  178. }