mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-05-06 21:52:54 +08:00
fix: inconsist checksum between image and its same format subimage (#22990)
Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
This commit is contained in:
@@ -320,10 +320,10 @@ func (manager *SImageManager) FetchCustomizeColumns(
|
||||
return rows
|
||||
}
|
||||
|
||||
func (self *SImage) GetExtraDetailsHeaders(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) map[string]string {
|
||||
func (img *SImage) GetExtraDetailsHeaders(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) map[string]string {
|
||||
headers := make(map[string]string)
|
||||
|
||||
details := ImageManager.FetchCustomizeColumns(ctx, userCred, query, []interface{}{self}, nil, false)
|
||||
details := ImageManager.FetchCustomizeColumns(ctx, userCred, query, []interface{}{img}, nil, false)
|
||||
extra := jsonutils.Marshal(details[0]).(*jsonutils.JSONDict)
|
||||
for _, k := range extra.SortedKeys() {
|
||||
if k == "properties" {
|
||||
@@ -335,8 +335,8 @@ func (self *SImage) GetExtraDetailsHeaders(ctx context.Context, userCred mcclien
|
||||
}
|
||||
}
|
||||
|
||||
jsonDict := jsonutils.Marshal(self).(*jsonutils.JSONDict)
|
||||
fields, _ := db.GetDetailFields(self.GetModelManager(), userCred)
|
||||
jsonDict := jsonutils.Marshal(img).(*jsonutils.JSONDict)
|
||||
fields, _ := db.GetDetailFields(img.GetModelManager(), userCred)
|
||||
for _, k := range jsonDict.SortedKeys() {
|
||||
if utils.IsInStringArray(k, fields) {
|
||||
val, _ := jsonDict.GetString(k)
|
||||
@@ -346,9 +346,16 @@ func (self *SImage) GetExtraDetailsHeaders(ctx context.Context, userCred mcclien
|
||||
}
|
||||
}
|
||||
|
||||
// none of subimage business
|
||||
var ossChksum = img.OssChecksum
|
||||
if len(img.OssChecksum) == 0 {
|
||||
ossChksum = img.Checksum
|
||||
}
|
||||
headers[fmt.Sprintf("%s%s", modules.IMAGE_META, "oss_checksum")] = ossChksum
|
||||
|
||||
formatStr := jsonutils.GetAnyString(query, []string{"format", "disk_format"})
|
||||
if len(formatStr) > 0 {
|
||||
subimg := ImageSubformatManager.FetchSubImage(self.Id, formatStr)
|
||||
subimg := ImageSubformatManager.FetchSubImage(img.Id, formatStr)
|
||||
if subimg != nil {
|
||||
headers[fmt.Sprintf("%s%s", modules.IMAGE_META, "disk_format")] = formatStr
|
||||
isTorrent := jsonutils.QueryBoolean(query, "torrent", false)
|
||||
@@ -356,6 +363,7 @@ func (self *SImage) GetExtraDetailsHeaders(ctx context.Context, userCred mcclien
|
||||
headers[fmt.Sprintf("%s%s", modules.IMAGE_META, "status")] = subimg.Status
|
||||
headers[fmt.Sprintf("%s%s", modules.IMAGE_META, "size")] = fmt.Sprintf("%d", subimg.Size)
|
||||
headers[fmt.Sprintf("%s%s", modules.IMAGE_META, "checksum")] = subimg.Checksum
|
||||
headers[fmt.Sprintf("%s%s", modules.IMAGE_META, "oss_checksum")] = subimg.Checksum
|
||||
} else {
|
||||
headers[fmt.Sprintf("%s%s", modules.IMAGE_META, "status")] = subimg.TorrentStatus
|
||||
headers[fmt.Sprintf("%s%s", modules.IMAGE_META, "size")] = fmt.Sprintf("%d", subimg.TorrentSize)
|
||||
@@ -364,22 +372,15 @@ func (self *SImage) GetExtraDetailsHeaders(ctx context.Context, userCred mcclien
|
||||
}
|
||||
}
|
||||
|
||||
// none of subimage business
|
||||
var ossChksum = self.OssChecksum
|
||||
if len(self.OssChecksum) == 0 {
|
||||
ossChksum = self.Checksum
|
||||
}
|
||||
headers[fmt.Sprintf("%s%s", modules.IMAGE_META, "oss_checksum")] = ossChksum
|
||||
|
||||
properties, _ := ImagePropertyManager.GetProperties(self.Id)
|
||||
properties, _ := ImagePropertyManager.GetProperties(img.Id)
|
||||
if len(properties) > 0 {
|
||||
for k, v := range properties {
|
||||
headers[fmt.Sprintf("%s%s", modules.IMAGE_META_PROPERTY, k)] = v
|
||||
}
|
||||
}
|
||||
|
||||
if self.PendingDeleted {
|
||||
pendingDeletedAt := self.PendingDeletedAt.Add(time.Second * time.Duration(options.Options.PendingDeleteExpireSeconds))
|
||||
if img.PendingDeleted {
|
||||
pendingDeletedAt := img.PendingDeletedAt.Add(time.Second * time.Duration(options.Options.PendingDeleteExpireSeconds))
|
||||
headers[fmt.Sprintf("%s%s", modules.IMAGE_META, "auto_delete_at")] = timeutils.FullIsoTime(pendingDeletedAt)
|
||||
}
|
||||
|
||||
@@ -1067,44 +1068,44 @@ func (self *SImage) newSubformat(ctx context.Context, format qemuimgfmt.TImageFo
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SImage) migrateSubImage(ctx context.Context) error {
|
||||
func (img *SImage) migrateSubImage(ctx context.Context) error {
|
||||
log.Debugf("migrateSubImage")
|
||||
if !qemuimgfmt.IsSupportedImageFormat(self.DiskFormat) {
|
||||
log.Warningf("Unsupported image format %s, no need to migrate", self.DiskFormat)
|
||||
if !qemuimgfmt.IsSupportedImageFormat(img.DiskFormat) {
|
||||
log.Warningf("Unsupported image format %s, no need to migrate", img.DiskFormat)
|
||||
return nil
|
||||
}
|
||||
|
||||
subimg := ImageSubformatManager.FetchSubImage(self.Id, self.DiskFormat)
|
||||
subimg := ImageSubformatManager.FetchSubImage(img.Id, img.DiskFormat)
|
||||
if subimg != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
imgInst, err := self.getQemuImage()
|
||||
imgInst, err := img.getQemuImage()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getQemuImage")
|
||||
}
|
||||
if self.GetImageType() != api.ImageTypeISO && imgInst.IsSparse() && utils.IsInStringArray(self.DiskFormat, options.Options.TargetImageFormats) {
|
||||
if img.GetImageType() != api.ImageTypeISO && imgInst.IsSparse() && utils.IsInStringArray(img.DiskFormat, options.Options.TargetImageFormats) {
|
||||
// need to convert again
|
||||
log.Debugf("migrateImage: image is not iso but sparse, need to convert the image")
|
||||
return self.newSubformat(ctx, qemuimgfmt.String2ImageFormat(self.DiskFormat), false)
|
||||
return img.newSubformat(ctx, qemuimgfmt.String2ImageFormat(img.DiskFormat), false)
|
||||
} else {
|
||||
log.Debugf("migrateImage: no need to convert the image")
|
||||
localPath := self.GetLocalLocation()
|
||||
if !strings.HasSuffix(localPath, fmt.Sprintf(".%s", self.DiskFormat)) {
|
||||
newLocalpath := fmt.Sprintf("%s.%s", localPath, self.DiskFormat)
|
||||
localPath := img.GetLocalLocation()
|
||||
if !strings.HasSuffix(localPath, fmt.Sprintf(".%s", img.DiskFormat)) {
|
||||
newLocalpath := fmt.Sprintf("%s.%s", localPath, img.DiskFormat)
|
||||
out, err := procutils.NewCommand("mv", "-f", localPath, newLocalpath).Output()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "rename file failed %s", out)
|
||||
}
|
||||
_, err = db.Update(self, func() error {
|
||||
self.Location = self.GetNewLocation(newLocalpath)
|
||||
_, err = db.Update(img, func() error {
|
||||
img.Location = img.GetNewLocation(newLocalpath)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return self.newSubformat(ctx, qemuimgfmt.String2ImageFormat(self.DiskFormat), true)
|
||||
return img.newSubformat(ctx, qemuimgfmt.String2ImageFormat(img.DiskFormat), true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1897,7 +1898,7 @@ func (image *SImage) doUploadPermanentStorage(ctx context.Context, userCred mccl
|
||||
if !subimgs[i].isLocal() {
|
||||
continue
|
||||
}
|
||||
if subimgs[i].Format == image.DiskFormat {
|
||||
if subimgs[i].Format == image.DiskFormat && subimgs[i].Checksum == image.Checksum {
|
||||
_, err := db.Update(&subimgs[i], func() error {
|
||||
subimgs[i].Location = image.Location
|
||||
subimgs[i].Status = api.IMAGE_STATUS_ACTIVE
|
||||
@@ -1909,7 +1910,7 @@ func (image *SImage) doUploadPermanentStorage(ctx context.Context, userCred mccl
|
||||
} else {
|
||||
imagePath := subimgs[i].GetLocalLocation()
|
||||
storage := GetStorage()
|
||||
location, err := GetStorage().SaveImage(ctx, imagePath)
|
||||
location, err := storage.SaveImage(ctx, imagePath)
|
||||
if err != nil {
|
||||
log.Errorf("Failed save image to sepcific storage %s", err)
|
||||
subimgs[i].SetStatus(api.IMAGE_STATUS_SAVE_FAIL)
|
||||
|
||||
Reference in New Issue
Block a user