image.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  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 ecloud
  15. import (
  16. "context"
  17. "fmt"
  18. "time"
  19. "yunion.io/x/jsonutils"
  20. "yunion.io/x/pkg/util/imagetools"
  21. api "yunion.io/x/cloudmux/pkg/apis/compute"
  22. "yunion.io/x/cloudmux/pkg/cloudprovider"
  23. "yunion.io/x/cloudmux/pkg/multicloud"
  24. )
  25. type SImage struct {
  26. multicloud.SImageBase
  27. EcloudTags
  28. SZoneRegionBase
  29. storageCache *SStoragecache
  30. imgInfo *imagetools.ImageInfo
  31. // 字段与 IMS OpenAPI listImageRespV2/getImageRespV2 对齐
  32. ImageId string `json:"imageId,omitempty"`
  33. ServerId string `json:"serverId,omitempty"`
  34. ImageAlias string `json:"imageAlias,omitempty"`
  35. Name string `json:"name,omitempty"`
  36. Url string `json:"url,omitempty"`
  37. SrourceImageId string `json:"sourceImageId,omitempty"`
  38. Status string `json:"status,omitempty"`
  39. SizeMb int `json:"size"` // IMS 返回 size,按 MB 处理
  40. IsPublic int `json:"isPublic,omitempty"`
  41. ImageSource string `json:"imageSource,omitempty"` // 通过 imageSource 判断是否公共镜像
  42. CreateTime time.Time `json:"-"` // 旧接口可能直接反序列化为 time.Time
  43. CreateTimeStr string `json:"createTime,omitempty"`
  44. Note string `json:"note,omitempty"`
  45. OsType string `json:"osType,omitempty"`
  46. MinDiskGB int `json:"minDisk,omitempty"`
  47. ImageType string `json:"imageType,omitempty"`
  48. PublicImageType string `json:"publicImageType,omitempty"`
  49. BackupType string `json:"backupType,omitempty"`
  50. BackupWay string `json:"backupWay,omitempty"`
  51. SnapshotId string `json:"snapshotId,omitempty"`
  52. OsName string `json:"osName,omitempty"`
  53. }
  54. func (r *SRegion) GetImage(imageId string) (*SImage, error) {
  55. // 使用 IMS OpenAPI 镜像详情:GET /api/openapi-ims/user/v5/image/{imageId}
  56. req := NewOpenApiEbsRequest(r.RegionId, fmt.Sprintf("/api/openapi-ims/user/v5/image/%s", imageId), nil, nil)
  57. var image SImage
  58. err := r.client.doGet(context.Background(), req.Base(), &image)
  59. if err != nil {
  60. return nil, err
  61. }
  62. return &image, nil
  63. }
  64. func (r *SRegion) GetImages(isPublic bool) ([]SImage, error) {
  65. // IMS 接口要求 region(资源池 ID),否则报 CSLOPENSTACK_COMPUTE_IMAGE_PARAM_INVALID
  66. poolId := regionIdToPoolId[r.RegionId]
  67. if poolId == "" {
  68. poolId = r.RegionId
  69. }
  70. // IMS OpenAPI ListImageRespV2
  71. // GET /api/openapi-ims/user/v5/image?region=CIDC-RP-xx&imageSource=PUBLIC|PRIVATE
  72. query := map[string]string{
  73. "region": poolId,
  74. }
  75. if isPublic {
  76. query["imageSource"] = "PUBLIC"
  77. } else {
  78. query["imageSource"] = "PRIVATE"
  79. }
  80. req := NewOpenApiEbsRequest(r.RegionId, "/api/openapi-ims/user/v5/image", query, nil)
  81. images := make([]SImage, 0, 20)
  82. if err := r.client.doList(context.Background(), req.Base(), &images); err != nil {
  83. return nil, err
  84. }
  85. return images, nil
  86. }
  87. func (i *SImage) GetCreatedAt() time.Time {
  88. if len(i.CreateTimeStr) > 0 {
  89. // IMS 接口时间格式一般为 "2006-01-02 15:04:05"
  90. if t, err := time.Parse("2006-01-02 15:04:05", i.CreateTimeStr); err == nil {
  91. return t
  92. }
  93. // 兼容 RFC3339
  94. if t, err := time.Parse(time.RFC3339, i.CreateTimeStr); err == nil {
  95. return t
  96. }
  97. }
  98. return i.CreateTime
  99. }
  100. func (i *SImage) GetId() string {
  101. return i.ImageId
  102. }
  103. func (i *SImage) GetName() string {
  104. return i.Name
  105. }
  106. func (i *SImage) GetGlobalId() string {
  107. return i.ImageId
  108. }
  109. func (i *SImage) GetStatus() string {
  110. switch i.Status {
  111. case "active":
  112. return api.CACHED_IMAGE_STATUS_ACTIVE
  113. case "queued":
  114. return api.CACHED_IMAGE_STATUS_INIT
  115. case "saving":
  116. return api.CACHED_IMAGE_STATUS_SAVING
  117. case "caching":
  118. return api.CACHED_IMAGE_STATUS_CACHING
  119. case "pending_delete":
  120. return api.CACHED_IMAGE_STATUS_DELETING
  121. default:
  122. return api.CACHED_IMAGE_STATUS_UNKNOWN
  123. }
  124. }
  125. func (i *SImage) Refresh() error {
  126. new, err := i.storageCache.region.GetImage(i.GetId())
  127. if err != nil {
  128. return err
  129. }
  130. return jsonutils.Update(i, new)
  131. }
  132. func (i *SImage) IsEmulated() bool {
  133. return false
  134. }
  135. func (i *SImage) getNormalizedImageInfo() *imagetools.ImageInfo {
  136. if i.imgInfo == nil {
  137. imgInfo := imagetools.NormalizeImageInfo(i.OsName, "", i.OsType, "", "")
  138. i.imgInfo = &imgInfo
  139. }
  140. return i.imgInfo
  141. }
  142. func (i *SImage) GetFullOsName() string {
  143. return i.OsName
  144. }
  145. func (i *SImage) GetOsType() cloudprovider.TOsType {
  146. return cloudprovider.TOsType(i.getNormalizedImageInfo().OsType)
  147. }
  148. func (i *SImage) GetOsArch() string {
  149. return i.getNormalizedImageInfo().OsArch
  150. }
  151. func (i *SImage) GetOsDist() string {
  152. return i.getNormalizedImageInfo().OsDistro
  153. }
  154. func (i *SImage) GetOsVersion() string {
  155. return i.getNormalizedImageInfo().OsVersion
  156. }
  157. func (i *SImage) GetOsLang() string {
  158. return i.getNormalizedImageInfo().OsLang
  159. }
  160. func (i *SImage) GetBios() cloudprovider.TBiosType {
  161. return cloudprovider.ToBiosType(i.getNormalizedImageInfo().OsBios)
  162. }
  163. func (i *SImage) GetMinOsDiskSizeGb() int {
  164. return i.MinDiskGB
  165. }
  166. func (i *SImage) GetMinRamSizeMb() int {
  167. return 0
  168. }
  169. func (i *SImage) GetImageFormat() string {
  170. return ""
  171. }
  172. func (self *SImage) Delete(ctx context.Context) error {
  173. return cloudprovider.ErrNotSupported
  174. }
  175. func (self *SImage) GetIStoragecache() cloudprovider.ICloudStoragecache {
  176. return nil
  177. }
  178. func (self *SImage) GetSizeByte() int64 {
  179. return int64(self.SizeMb) * 1024 * 1024
  180. }
  181. func (self *SImage) GetImageType() cloudprovider.TImageType {
  182. if self.IsPublic == 1 {
  183. return cloudprovider.ImageTypeSystem
  184. }
  185. return cloudprovider.ImageTypeCustomized
  186. }
  187. func (self *SImage) GetImageStatus() string {
  188. return cloudprovider.IMAGE_STATUS_ACTIVE
  189. }