fix: image self check status (#23252)

Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
This commit is contained in:
Jian Qiu
2025-09-10 18:57:53 +08:00
committed by GitHub
co-authored by Qiu Jian
parent 3ddd2603f8
commit 0777418c63
4 changed files with 85 additions and 0 deletions
+15
View File
@@ -389,3 +389,18 @@ func (self *SImageSubformat) SetStatusSeeding(seeding bool) {
torrent.SetTorrentSeeding(filePath, seeding)
}
}
func (subimg *SImageSubformat) verifyStatusSelf(ctx context.Context) error {
if len(subimg.Location) == 0 {
return nil
}
filePath := subimg.Location
_, rc, err := GetImage(ctx, filePath)
if err != nil {
subimg.SetStatus(api.IMAGE_STATUS_UNKNOWN)
return errors.Wrap(err, "GetImage")
}
defer rc.Close()
subimg.SetStatus(api.IMAGE_STATUS_ACTIVE)
return nil
}
+66
View File
@@ -2328,3 +2328,69 @@ func (img *SImage) markDataImage(userCred mcclient.TokenCredential) error {
db.OpsLog.LogEvent(img, db.ACT_UPDATE, diff, userCred)
return nil
}
func (manager *SImageManager) FetchImages(filter func(q *sqlchemy.SQuery) *sqlchemy.SQuery) ([]SImage, error) {
q := manager.Query()
if filter != nil {
q = filter(q)
}
images := make([]SImage, 0)
err := db.FetchModelObjects(manager, q, &images)
if err != nil {
return nil, errors.Wrap(err, "db.FetchModelObjects")
}
return images, nil
}
func (manager *SImageManager) VerifyActiveImageStatus(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
images, err := manager.FetchImages(func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
return q.In("status", []string{api.IMAGE_STATUS_ACTIVE, api.IMAGE_STATUS_UNKNOWN})
})
if err != nil {
log.Errorf("FetchImages failed: %s", err)
return
}
for i := range images {
img := &images[i]
err := img.verifyStatus(ctx, userCred)
if err != nil {
log.Errorf("VerifyStatus %s(%s) failed: %s", img.Id, img.Name, err)
}
}
}
func (img *SImage) verifyStatus(ctx context.Context, userCred mcclient.TokenCredential) error {
errs := make([]error, 0)
subImages := ImageSubformatManager.GetAllSubImages(img.Id)
for i := range subImages {
err := subImages[i].verifyStatusSelf(ctx)
if err != nil {
errs = append(errs, err)
}
}
err := img.verifyStatusSelf(ctx, userCred)
if err != nil {
errs = append(errs, err)
}
if len(errs) > 0 {
return errors.NewAggregate(errs)
}
return nil
}
func (img *SImage) verifyStatusSelf(ctx context.Context, userCred mcclient.TokenCredential) error {
if len(img.Location) == 0 {
return nil
}
filePath := img.Location
_, rc, err := GetImage(ctx, filePath)
if err != nil {
img.SetStatus(ctx, userCred, api.IMAGE_STATUS_UNKNOWN, errors.Wrap(err, "verifyStatusSelf").Error())
return errors.Wrap(err, "GetImage")
}
defer rc.Close()
if img.Status != api.IMAGE_STATUS_ACTIVE {
img.SetStatus(ctx, userCred, api.IMAGE_STATUS_ACTIVE, "verifyStatusSelf")
}
return nil
}
+2
View File
@@ -55,6 +55,8 @@ type SImageOptions struct {
S3CheckImageStatus bool `help:"Enable s3 check image status"`
ImageStreamWorkerCount int `help:"Image stream worker count" default:"10"`
VerifyImageStatusIntervalMinutes int `help:"verify image status periodically, default 15 minutes" default:"15"`
}
var (
+2
View File
@@ -158,6 +158,8 @@ func StartService() {
cron.AddJobEveryFewHour("AutoPurgeSplitable", 4, 30, 0, db.AutoPurgeSplitable, false)
cron.AddJobAtIntervals("MarkDataImage", time.Duration(options.Options.VerifyImageStatusIntervalMinutes)*time.Minute, models.ImageManager.VerifyActiveImageStatus)
cron.Start()
}