When updating mirror repo intervals by API reschedule next update too (#19429) (#19433)

Backport #19429

When a mirror repo interval is updated by the UI it is rescheduled with that interval
however the API does not do this. The API also lacks the enable_prune option.

This PR adds this functionality in to the API Edit Repo endpoint.

Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
zeripath 2022-04-20 15:04:26 +01:00 committed by GitHub
parent 9c2212df15
commit 08eecba32b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 61 additions and 29 deletions

View file

@ -183,6 +183,8 @@ type EditRepoOption struct {
Archived *bool `json:"archived,omitempty"` Archived *bool `json:"archived,omitempty"`
// set to a string like `8h30m0s` to set the mirror interval time // set to a string like `8h30m0s` to set the mirror interval time
MirrorInterval *string `json:"mirror_interval,omitempty"` MirrorInterval *string `json:"mirror_interval,omitempty"`
// enable prune - remove obsolete remote-tracking references
EnablePrune *bool `json:"enable_prune,omitempty"`
} }
// GenerateRepoOption options when creating repository using a template // GenerateRepoOption options when creating repository using a template

View file

@ -624,7 +624,7 @@ func Edit(ctx *context.APIContext) {
} }
if opts.MirrorInterval != nil { if opts.MirrorInterval != nil {
if err := updateMirrorInterval(ctx, opts); err != nil { if err := updateMirror(ctx, opts); err != nil {
return return
} }
} }
@ -949,37 +949,67 @@ func updateRepoArchivedState(ctx *context.APIContext, opts api.EditRepoOption) e
return nil return nil
} }
// updateMirrorInterval updates the repo's mirror Interval // updateMirror updates a repo's mirror Interval and EnablePrune
func updateMirrorInterval(ctx *context.APIContext, opts api.EditRepoOption) error { func updateMirror(ctx *context.APIContext, opts api.EditRepoOption) error {
repo := ctx.Repo.Repository repo := ctx.Repo.Repository
// only update mirror if interval or enable prune are provided
if opts.MirrorInterval == nil && opts.EnablePrune == nil {
return nil
}
// these values only make sense if the repo is a mirror
if !repo.IsMirror {
err := fmt.Errorf("repo is not a mirror, can not change mirror interval")
ctx.Error(http.StatusUnprocessableEntity, err.Error(), err)
return err
}
// get the mirror from the repo
mirror, err := repo_model.GetMirrorByRepoID(repo.ID)
if err != nil {
log.Error("Failed to get mirror: %s", err)
ctx.Error(http.StatusInternalServerError, "MirrorInterval", err)
return err
}
// update MirrorInterval
if opts.MirrorInterval != nil { if opts.MirrorInterval != nil {
if !repo.IsMirror {
err := fmt.Errorf("repo is not a mirror, can not change mirror interval") // MirrorInterval should be a duration
ctx.Error(http.StatusUnprocessableEntity, err.Error(), err) interval, err := time.ParseDuration(*opts.MirrorInterval)
return err
}
mirror, err := repo_model.GetMirrorByRepoID(repo.ID)
if err != nil { if err != nil {
log.Error("Failed to get mirror: %s", err)
ctx.Error(http.StatusInternalServerError, "MirrorInterval", err)
return err
}
if interval, err := time.ParseDuration(*opts.MirrorInterval); err == nil {
mirror.Interval = interval
mirror.Repo = repo
if err := repo_model.UpdateMirror(mirror); err != nil {
log.Error("Failed to Set Mirror Interval: %s", err)
ctx.Error(http.StatusUnprocessableEntity, "MirrorInterval", err)
return err
}
log.Trace("Repository %s/%s Mirror Interval was Updated to %s", ctx.Repo.Owner.Name, repo.Name, interval)
} else {
log.Error("Wrong format for MirrorInternal Sent: %s", err) log.Error("Wrong format for MirrorInternal Sent: %s", err)
ctx.Error(http.StatusUnprocessableEntity, "MirrorInterval", err) ctx.Error(http.StatusUnprocessableEntity, "MirrorInterval", err)
return err return err
} }
// Ensure the provided duration is not too short
if interval != 0 && interval < setting.Mirror.MinInterval {
err := fmt.Errorf("invalid mirror interval: %s is below minimum interval: %s", interval, setting.Mirror.MinInterval)
ctx.Error(http.StatusUnprocessableEntity, "MirrorInterval", err)
return err
}
mirror.Interval = interval
mirror.Repo = repo
mirror.ScheduleNextUpdate()
log.Trace("Repository %s Mirror[%d] Set Interval: %s NextUpdateUnix: %s", repo.FullName(), mirror.ID, interval, mirror.NextUpdateUnix)
} }
// update EnablePrune
if opts.EnablePrune != nil {
mirror.EnablePrune = *opts.EnablePrune
log.Trace("Repository %s Mirror[%d] Set EnablePrune: %t", repo.FullName(), mirror.ID, mirror.EnablePrune)
}
// finally update the mirror in the DB
if err := repo_model.UpdateMirror(mirror); err != nil {
log.Error("Failed to Set Mirror Interval: %s", err)
ctx.Error(http.StatusUnprocessableEntity, "MirrorInterval", err)
return err
}
return nil return nil
} }

View file

@ -31,7 +31,6 @@ import (
"code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/typesniffer" "code.gitea.io/gitea/modules/typesniffer"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/modules/validation"
@ -194,11 +193,7 @@ func SettingsPost(ctx *context.Context) {
} else { } else {
ctx.Repo.Mirror.EnablePrune = form.EnablePrune ctx.Repo.Mirror.EnablePrune = form.EnablePrune
ctx.Repo.Mirror.Interval = interval ctx.Repo.Mirror.Interval = interval
if interval != 0 { ctx.Repo.Mirror.ScheduleNextUpdate()
ctx.Repo.Mirror.NextUpdateUnix = timeutil.TimeStampNow().AddDuration(interval)
} else {
ctx.Repo.Mirror.NextUpdateUnix = 0
}
if err := repo_model.UpdateMirror(ctx.Repo.Mirror); err != nil { if err := repo_model.UpdateMirror(ctx.Repo.Mirror); err != nil {
ctx.Data["Err_Interval"] = true ctx.Data["Err_Interval"] = true
ctx.RenderWithErr(ctx.Tr("repo.mirror_interval_invalid"), tplSettingsOptions, &form) ctx.RenderWithErr(ctx.Tr("repo.mirror_interval_invalid"), tplSettingsOptions, &form)

View file

@ -14757,6 +14757,11 @@
"type": "string", "type": "string",
"x-go-name": "Description" "x-go-name": "Description"
}, },
"enable_prune": {
"description": "enable prune - remove obsolete remote-tracking references",
"type": "boolean",
"x-go-name": "EnablePrune"
},
"external_tracker": { "external_tracker": {
"$ref": "#/definitions/ExternalTracker" "$ref": "#/definitions/ExternalTracker"
}, },