fix: inconsist checksum between image and its same format subimage (#22990)

Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
This commit is contained in:
Jian Qiu
2025-07-30 01:45:09 +08:00
committed by GitHub
parent 02adf756f4
commit 9504f49e98

View File

@@ -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)