cloudimages.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  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 models
  15. import (
  16. "context"
  17. "database/sql"
  18. "yunion.io/x/log"
  19. "yunion.io/x/pkg/errors"
  20. "yunion.io/x/pkg/gotypes"
  21. "yunion.io/x/onecloud/pkg/cloudcommon/db"
  22. "yunion.io/x/onecloud/pkg/compute/options"
  23. "yunion.io/x/onecloud/pkg/mcclient"
  24. "yunion.io/x/onecloud/pkg/mcclient/auth"
  25. "yunion.io/x/onecloud/pkg/util/yunionmeta"
  26. )
  27. // +onecloud:swagger-gen-ignore
  28. type SCloudimageManager struct {
  29. db.SStandaloneResourceBaseManager
  30. db.SExternalizedResourceBaseManager
  31. }
  32. var CloudimageManager *SCloudimageManager
  33. func init() {
  34. CloudimageManager = &SCloudimageManager{
  35. SStandaloneResourceBaseManager: db.NewStandaloneResourceBaseManager(
  36. SCloudimage{},
  37. "cloudimages_tbl",
  38. "cloudimage",
  39. "cloudimages",
  40. ),
  41. }
  42. CloudimageManager.SetVirtualObject(CloudimageManager)
  43. }
  44. // +onecloud:swagger-gen-ignore
  45. type SCloudimage struct {
  46. db.SStandaloneResourceBase
  47. db.SExternalizedResourceBase
  48. SCloudregionResourceBase `width:"36" charset:"ascii" nullable:"false" list:"user" default:"default" create:"optional" json:"cloudregion_id" index:"true"`
  49. }
  50. func SyncPublicCloudImages(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
  51. if isStart {
  52. cnt, err := CloudimageManager.Query().CountWithError()
  53. if err != nil {
  54. return
  55. }
  56. if cnt > 0 {
  57. log.Infof("Public cloud image has already synced, skip syncing")
  58. return
  59. }
  60. }
  61. regions := []SCloudregion{}
  62. q := CloudregionManager.Query().In("provider", CloudproviderManager.GetPublicProviderProvidersQuery())
  63. err := db.FetchModelObjects(CloudregionManager, q, &regions)
  64. if err != nil {
  65. return
  66. }
  67. if len(regions) == 0 {
  68. return
  69. }
  70. meta, err := yunionmeta.FetchYunionmeta(ctx)
  71. if err != nil {
  72. log.Errorf("FetchYunionmeta %v", err)
  73. return
  74. }
  75. index, err := meta.Index(CloudimageManager.Keyword())
  76. if err != nil {
  77. log.Errorf("getServerSkuIndex error: %v", err)
  78. return
  79. }
  80. for i := range regions {
  81. region := &regions[i]
  82. skuMeta := &SCloudimage{}
  83. skuMeta.SetModelManager(CloudimageManager, skuMeta)
  84. skuMeta.Id = region.ExternalId
  85. oldMd5 := db.Metadata.GetStringValue(ctx, skuMeta, db.SKU_METADAT_KEY, userCred)
  86. newMd5, ok := index[region.ExternalId]
  87. if !ok || newMd5 == yunionmeta.EMPTY_MD5 || len(oldMd5) > 0 && newMd5 == oldMd5 {
  88. continue
  89. }
  90. db.Metadata.SetValue(ctx, skuMeta, db.SKU_METADAT_KEY, newMd5, userCred)
  91. err = regions[i].SyncCloudImages(ctx, userCred, !isStart, false)
  92. if err != nil {
  93. continue
  94. }
  95. storagecaches, err := regions[i].GetStoragecaches()
  96. if err != nil {
  97. log.Errorf("GetStoragecaches for region %s(%s) error: %v", regions[i].Name, regions[i].Id, err)
  98. }
  99. for j := range storagecaches {
  100. err = storagecaches[j].CheckCloudimages(ctx, userCred, regions[i].Name, regions[i].Id)
  101. if err != nil {
  102. log.Errorf("SyncSystemImages for region %s(%s) storagecache %s error: %v", regions[i].Name, regions[i].Id, storagecaches[j].Name, err)
  103. }
  104. }
  105. }
  106. return
  107. }
  108. func (self *SCloudimage) syncRemove(ctx context.Context, userCred mcclient.TokenCredential) error {
  109. _image, err := db.FetchByExternalId(CachedimageManager, self.ExternalId)
  110. if err != nil {
  111. if errors.Cause(err) == sql.ErrNoRows {
  112. return self.Delete(ctx, userCred)
  113. }
  114. return errors.Wrapf(err, "db.FetchByExternalId(%s)", self.ExternalId)
  115. }
  116. image := _image.(*SCachedimage)
  117. err = image.ValidateDeleteCondition(ctx, nil)
  118. if err == nil {
  119. image.Delete(ctx, userCred)
  120. }
  121. return self.Delete(ctx, userCred)
  122. }
  123. func (self *SCloudimage) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
  124. return db.RealDeleteModel(ctx, userCred, self)
  125. }
  126. func (self *SCloudimage) syncWithImage(ctx context.Context, userCred mcclient.TokenCredential, image SCachedimage, region *SCloudregion) error {
  127. meta, err := yunionmeta.FetchYunionmeta(ctx)
  128. if err != nil {
  129. return err
  130. }
  131. skuUrl := region.getMetaUrl(meta.ImageBase, image.GetGlobalId())
  132. s := auth.GetAdminSession(ctx, options.Options.Region)
  133. obj, err := db.FetchByExternalId(CachedimageManager, image.GetGlobalId())
  134. if err != nil {
  135. if errors.Cause(err) != sql.ErrNoRows {
  136. return errors.Wrapf(err, "db.FetchByExternalId(%s)", image.GetGlobalId())
  137. }
  138. cachedImage := &SCachedimage{}
  139. cachedImage.SetModelManager(CachedimageManager, cachedImage)
  140. err = meta.Get(skuUrl, cachedImage)
  141. if err != nil {
  142. return errors.Wrapf(err, "Get")
  143. }
  144. cachedImage.IsPublic = true
  145. cachedImage.ProjectId = s.GetProjectId()
  146. err = CachedimageManager.TableSpec().Insert(ctx, cachedImage)
  147. if err != nil {
  148. return errors.Wrapf(err, "Insert cachedimage")
  149. }
  150. return nil
  151. }
  152. cachedImage := obj.(*SCachedimage)
  153. _, err = db.Update(cachedImage, func() error {
  154. if gotypes.IsNil(cachedImage.Info) {
  155. err = meta.Get(skuUrl, &image)
  156. if err != nil {
  157. return errors.Wrapf(err, "Get")
  158. }
  159. cachedImage.Info = image.Info
  160. cachedImage.Size = image.Size
  161. cachedImage.UEFI = image.UEFI
  162. }
  163. if cachedImage.ProjectId == "system" {
  164. cachedImage.ProjectId = s.GetProjectId()
  165. }
  166. return nil
  167. })
  168. if err != nil {
  169. return errors.Wrapf(err, "Update cachedimage")
  170. }
  171. return nil
  172. }